﻿using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay.PointMarkers;
/** Copyright © 2010-2015 Vahid Jalili
 * 
 * This file is part of ReShapes project.
 * ReShapes is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 * ReShapes is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with Foobar. If not, see http://www.gnu.org/licenses/.
 **/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace ReShapes
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DateTime Start;
        DispatcherTimer DT_Reasoning_Run_Time = new DispatcherTimer();

        private BackgroundWorker Run_Reasoning_Background_Worker = new BackgroundWorker();
        private BackgroundWorker Draw_Chart_A_Background_Worder = new BackgroundWorker();
        private BackgroundWorker Draw_Chart_B_Background_Worder = new BackgroundWorker();
        private BackgroundWorker Save_Drawn_Figure = new BackgroundWorker();
        private BackgroundWorker Add_Random_Pixels_BW = new BackgroundWorker();
        private BackgroundWorker Clear_Drawn_Charts = new BackgroundWorker();


        #region +=+       Double, Integer and Boolean Variables Declaration       +=+

        const double pi = Math.PI;

        double
            P_H = 0,
            P_W = 0,
            Fig_A_Animation_X_Step_Size = 0,
            Fig_A_Animation_Y_Step_Size = 0,
            Drawing_Progress_Step_Size = 1,
            Trans_move_X = 0,
            Trans_move_Y = 0,
            Trans_Rotation = 0,
            Epsilon = 2.0,
            Default_Epsilon = 2.0;

        int
            max_x = 0, max_y = 0,
            matrix_Size = 0,
            number_of_drawn_figures = 0,
            Ill_Fig_A_index = 0,
            Ill_Fig_B_index = 0,
            Iteration_index_to_be_Shown = 0,
            Last_turned_on_Pixels_for_preview = 0,
            Reasoning_Time_MS = 0,
            Reasoning_Time_S = 0,
            Reasoning_Time_M = 0,
            Reasoning_Time_H = 0,
            Figure_A_index = -1,
            Figure_B_index = 0,
            Engine_index = -1,
            Type_of_Data_to_show = 0,
            d = 2,
            Omega = 3,
            Lambda = 10,
            Upsilon = 10,
            Default_d = 2,
            Default_Omega = 3,
            Default_Lambda = 10,
            Default_Upsilon = 10;

        bool
            Drawing_Preview_of_New_Figure = false,
            Ill_shown_once_before = false,
            SCV = false;

        #endregion


        #region +=+                 Essential Classes Declaration                 +=+

        public class Figurez
        {
            public string Figure_ID { set; get; }
            public string Figure_Name { set; get; }
        }

        public class Compared_Figures
        {
            public string Figure_1 { set; get; }
            public string Figure_2 { set; get; }
        }

        public class Iteration_Results_Class
        {
            public string Title { set; get; }
            public string Time { set; get; }
        }

        private class Alpha_Details
        {
            public int index { set; get; }
            public int C_Shift { set; get; }
            public double Corresponding_Rotation_Angle { set; get; }
        }
        private class Gamma_Details
        {
            public int index { set; get; }
            public int N { set; get; }
            public int M { set; get; }
            public int Value { set; get; }
            public int FigAValue { set; get; }
            public int FigBValue { set; get; }
        }
        private class Results_Details
        {
            public int index { set; get; }
            public double Match_Ratio { set; get; }
            public int C_Shift { set; get; }
            public double Corresponding_Rotation_Angle { set; get; }

            // followings could be eliminated, they give only extra info 
            public string Matched_Landmarks { set; get; }
            public string Matched_Regions { set; get; }
        }
        #endregion


        #region +=+                       List Declaration                        +=+

        List<string> Figures_Name = new List<string>();
        List<List<bool>> temp_Matrix = new List<List<bool>>();
        List<List<List<bool>>> Figures = new List<List<List<bool>>>();
        Dictionary<Point, bool> Preview_Pixels = new Dictionary<Point, bool>();

        List<Reasoning_Engine> Engine = new List<Reasoning_Engine>();

        ObservableCollection<Alpha_Details> Data_Alpha_Set = new ObservableCollection<Alpha_Details>();
        ObservableCollection<Gamma_Details> Data_Gamma_Set = new ObservableCollection<Gamma_Details>();
        ObservableCollection<Results_Details> Data_Results = new ObservableCollection<Results_Details>();

        ObservableCollection<Iteration_Results_Class> Iteration_Results = new ObservableCollection<Iteration_Results_Class>();

        #endregion

        
        #region +=+                   Custom Colors Declaration                   +=+

        SolidColorBrush Draw_n_Review_Pixel_Brush = new SolidColorBrush(Colors.Blue);
        SolidColorBrush Fig_A_Animation_Pixel_Brush = new SolidColorBrush(Colors.Blue);
        SolidColorBrush Fig_B_Animation_Pixel_Brush = new SolidColorBrush(Colors.OrangeRed);
        SolidColorBrush Button_Mouse_Enter_Color = new SolidColorBrush(Colors.Yellow);
        SolidColorBrush Button_Mouse_Leave_Color = new SolidColorBrush(Colors.White);

        #endregion  
      

                
        
        public MainWindow()
        {
            InitializeComponent();

            Iterations_DG.ItemsSource = Iteration_Results;

            Run_Reasoning_Background_Worker.DoWork += new DoWorkEventHandler(Run_Reasoning_Background_Worker_DoWork);
            Run_Reasoning_Background_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Run_Reasoning_Background_Worker_RunWorkerCompleted);
            Run_Reasoning_Background_Worker.ProgressChanged += new ProgressChangedEventHandler(Run_Reasoning_Background_Worker_ProgressChanged);
            Run_Reasoning_Background_Worker.WorkerReportsProgress = true;

            Draw_Chart_A_Background_Worder.DoWork += Draw_Chart_A_Background_Worder_DoWork;
            Draw_Chart_A_Background_Worder.RunWorkerCompleted += Draw_Chart_A_Background_Worder_RunWorkerCompleted;

            Draw_Chart_B_Background_Worder.DoWork += Draw_Chart_B_Background_Worder_DoWork;
            Draw_Chart_B_Background_Worder.RunWorkerCompleted += Draw_Chart_B_Background_Worder_RunWorkerCompleted;

            Clear_Drawn_Charts.DoWork += Clear_Drawn_Charts_DoWork;
            Clear_Drawn_Charts.RunWorkerCompleted += Clear_Drawn_Charts_RunWorkerCompleted;
            Clear_Drawn_Charts.WorkerSupportsCancellation = true;

            Save_Drawn_Figure.DoWork += Save_Drawn_Figure_DoWork;
            Save_Drawn_Figure.RunWorkerCompleted += Save_Drawn_Figure_RunWorkerCompleted;

            Add_Random_Pixels_BW.DoWork += Add_Random_Pixels_BW_DoWork;
            Add_Random_Pixels_BW.RunWorkerCompleted += Add_Random_Pixels_BW_RunWorkerCompleted;
            Add_Random_Pixels_BW.ProgressChanged += Add_Random_Pixels_BW_ProgressChanged;
            Add_Random_Pixels_BW.WorkerReportsProgress = true;

            VerticalAxisTitle.Content = "Match Score\n";
            HorizontalAxisTitle.Content = "\nRotation Angles";

        }

        

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DT_Reasoning_Run_Time.Tick += new EventHandler(DT_Reasoning_Run_Time_Tick);
            DT_Reasoning_Run_Time.Interval = new TimeSpan(0, 0, 0, 0, 1);
        }

        private void Process_and_Details_Tab_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            New_Figure_Canvas.Width = 550;
            New_Figure_Canvas.Height = 550;
        }


        #region -_-           Main Buttons and Review Figure           -_-

        // Main Tab Selection , Selection Changed
        private void Process_and_Details_Tab_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (Process_and_Details_Tab.SelectedIndex != 4 &&
                Clearing_Drawn_Chart_L != null &&
                Clear_Drawn_Charts != null)
            {
                if (Fig_A_Chart_Canvas.Children.Count > 10 ||
                    Fig_B_Chart_Canvas.Children.Count > 10)
                {
                    Clearing_Drawn_Chart_L.Visibility = Visibility.Visible;

                    while (Clear_Drawn_Charts.IsBusy == true) { }

                    Clear_Drawn_Charts.RunWorkerAsync();
                }
            }
        }


        // Exit button
        private void Exit_BT_MouseEnter(object sender, MouseEventArgs e)
        {
            Exit_BT.Foreground = Button_Mouse_Enter_Color;
        }
        private void Exit_BT_MouseLeave(object sender, MouseEventArgs e)
        {
            Exit_BT.Foreground = Button_Mouse_Leave_Color;
        }
        private void Exit_BT_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.Shutdown();
        }


        // Save button
        private void Save_B_MouseEnter(object sender, MouseEventArgs e)
        {
            Save_B.Foreground = Button_Mouse_Enter_Color;
        }
        private void Save_B_MouseLeave(object sender, MouseEventArgs e)
        {
            Save_B.Foreground = Button_Mouse_Leave_Color;
        }
        private void Save_B_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Microsoft.Win32.SaveFileDialog File_Save_Dialog = new Microsoft.Win32.SaveFileDialog();
            File_Save_Dialog.AddExtension = true;

            Nullable<bool> result = File_Save_Dialog.ShowDialog();

            StreamWriter Stream_Writer = new StreamWriter(File_Save_Dialog.FileName + ".txt");

            Stream_Writer.WriteLine(FSW_TB.Text + "," + FSH_TB.Text);
            for (int i = 0; i < Figures_Name.Count; i++)
            {
                Stream_Writer.WriteLine("N," + Figures_Name[i]);

                for (int x = 0; x < max_x; x++)
                    for (int y = 0; y < max_y; y++)
                        if (Figures[i][x][y] == true)
                            Stream_Writer.WriteLine(x.ToString() + "," + y.ToString());

                Stream_Writer.WriteLine("E,");
            }
            Stream_Writer.WriteLine("F,");

            Stream_Writer.Close();

            MessageBox.Show(
                "Finished Saving Figures",
                "Save",
                MessageBoxButton.OK,
                MessageBoxImage.Information);
        }


        // Load button
        private void Load_B_MouseEnter(object sender, MouseEventArgs e)
        {
            Load_B.Foreground = Button_Mouse_Enter_Color;
        }
        private void Load_B_MouseLeave(object sender, MouseEventArgs e)
        {
            Load_B.Foreground = Button_Mouse_Leave_Color;
        }
        private void Load_B_MouseDown(object sender, MouseButtonEventArgs e)
        {
            System.IO.FileStream File_Stream;
            System.IO.TextReader Text_Reader;

            Microsoft.Win32.OpenFileDialog File_Chooser = new Microsoft.Win32.OpenFileDialog();
            File_Chooser.Multiselect = false;
            File_Chooser.Filter = "Text files (*.txt)|*.txt|BMP files (*.bmp)|*.bmp";
            Nullable<bool> result = File_Chooser.ShowDialog();

            if (result == true)
            {
                string[] R_index;
                string Line = "Hamed";
                string Path_info = System.IO.Path.GetFullPath(File_Chooser.FileName);

                switch (System.IO.Path.GetExtension(Path_info).ToLower())
                {
                    case ".txt":
                        #region ...   Load txt file   ...

                        File_Stream = new System.IO.FileStream(Path_info, FileMode.Open, FileAccess.Read);
                        Text_Reader = new System.IO.StreamReader(File_Stream);

                        Line = Text_Reader.ReadLine();
                        R_index = Line.Split(',');
                        max_x = Convert.ToInt32(R_index[0]);
                        max_y = Convert.ToInt32(R_index[1]);
                        FSW_TB.Text = R_index[0];
                        FSH_TB.Text = R_index[1];
                        Reset_for_new_Start();

                        FSW_TB.Text = max_x.ToString();
                        FSH_TB.Text = max_y.ToString();


                        bool END = false;
                        while (!END)
                        {
                            Line = Text_Reader.ReadLine();
                            R_index = Line.Split(',');

                            switch (R_index[0])
                            {
                                case "N":
                                    Figures_Name.Add(R_index[1]);
                                    break;

                                case "E":
                                    number_of_drawn_figures++;
                                    Copy_Temp_Matrix_2_Figures();
                                    Reset_temp_Matrix();
                                    break;

                                case "F":
                                    END = true;
                                    Create_Drawn_Figures();
                                    break;

                                default:
                                    temp_Matrix[Convert.ToInt32(R_index[0])][Convert.ToInt32(R_index[1])] = true;
                                    break;
                            }
                        }
                        #endregion
                        break;

                    case ".bmp":
                        #region ...   Load bmp file   ...

                        BitmapImage image = new BitmapImage(new Uri(Path_info));
                        PixelFormat pixelFormat = image.Format;
                        if(pixelFormat.BitsPerPixel != 32)
                        {
                            MessageBox.Show("The selected image is of " + pixelFormat.ToString() + " pixel format with " +
                                pixelFormat.BitsPerPixel + " bits-per-pixel representation which is not supported. \nChoose an image of 32 bits-per-pixel format.",
                                "Unsupported image format", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        int stride = image.PixelWidth * 4;
                        byte[] pixels = new byte[image.PixelHeight * stride];
                        image.CopyPixels(pixels, stride, 0);

                        double luminance = 0;
                        //double average = 0;

                        max_x = image.PixelWidth;
                        max_y = image.PixelHeight;
                        FSW_TB.Text = max_x.ToString();
                        FSH_TB.Text = max_y.ToString();
                        Reset_for_new_Start();

                        FSW_TB.Text = max_x.ToString();
                        FSH_TB.Text = max_y.ToString();

                        Figures_Name.Add(System.IO.Path.GetFileNameWithoutExtension(Path_info));

                        for (int x = 0; x < max_x; x ++)
                            for (int y = 0; y < max_y; y++)
                            {
                                luminance = 0.2126 * pixels[(x * 4) + (y * stride) + 1] + 0.7152 * pixels[(x * 4) + (y * stride) + 2] + 0.0722 * pixels[(x * 4) + (y * stride) + 3];
                                //average = (pixels[(x * 4) + (y * stride) + 1] + pixels[(x * 4) + (y * stride) + 2] + pixels[(x * 4) + (y * stride) + 3]) / 3;
                                temp_Matrix[x][y] = Math.Floor(luminance / 128) == 0 ? true : false;
                            }

                        number_of_drawn_figures++;
                        Copy_Temp_Matrix_2_Figures();
                        Create_Drawn_Figures();

                        #endregion
                        break;

                    default: return;
                }

                

                my_MessageBox mMB = new my_MessageBox();

                my_MessageBox my_msgbox = new my_MessageBox();
                my_msgbox.Show("\n\nFigure(s) are loaded succesfully.", 2);

                my_msgbox.ShowDialog();
            }
            else
            {

            }
        }


        // Reset button
        private void Reset_BT_MouseEnter(object sender, MouseEventArgs e)
        {
            Reset_BT.Foreground = Button_Mouse_Enter_Color;
        }
        private void Reset_BT_MouseLeave(object sender, MouseEventArgs e)
        {
            Reset_BT.Foreground = Button_Mouse_Leave_Color;
        }
        private void Reset_BT_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Reset_for_new_Start();

            FSW_TB.Text = "50";
            FSH_TB.Text = "50";
        }


        // Export Results
        private void Export_BT_MouseEnter(object sender, MouseEventArgs e)
        {
            Export_BT.Foreground = Button_Mouse_Enter_Color;
        }
        private void Export_BT_MouseLeave(object sender, MouseEventArgs e)
        {
            Export_BT.Foreground = Button_Mouse_Leave_Color;
        }
        private void Export_BT_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Export_Results EPR = new Export_Results();
            EPR.ShowDialog();

            string[] exp_rq = EPR.Result();

            #region -_-         Print Resoning Results          -_-

            if (exp_rq[1] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Reasoning Results\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Reasoning Results\\");

                for (int c = 0; c < Iteration_Results.Count; c++)
                {
                    using (
                        StreamWriter Fig_A =
                            new StreamWriter(
                                exp_rq[0] +
                                "\\Reasoning Results\\" + Figures_Name[0] + " [L-" + (Omega + c).ToString() + "].txt"))
                    {
                        Fig_A.WriteLine("Match Score\tCircular Shift\tRotation Angle\tMatched Landmark Points\tMatched Regions");

                        for (
                            int i = 0;
                            i < Engine[Compared_Figs_DG.SelectedIndex].
                            Iterations[c].Results.Count;
                            i++)
                        {
                            Fig_A.WriteLine(
                                (Math.Round((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Match_Score, 2)).ToString() + "\t" +
                                ((int)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].C_Shitfs).ToString() + "\t" +
                                ((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle).ToString() + "\t" +
                                ((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Matched_Landmarks_Count).ToString() + "  ( " +
                                ((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Matched_Landmarks_Ratio).ToString() + " % )\t" +
                                ((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Matched_Regions).ToString() + "  ( " +
                                ((double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Matched_Regions_Ratio).ToString() + " % )");
                        }
                    }
                }
            }
            #endregion

            #region -_-     Print Resoning Results Overview     -_-

            if (!Directory.Exists(exp_rq[0]))
                Directory.CreateDirectory(exp_rq[0]);

            if (!Directory.Exists(exp_rq[0] + "\\Reasoning Results\\"))
                Directory.CreateDirectory(exp_rq[0] + "\\Reasoning Results\\");

            var tDic = new SortedDictionary<double, double[]>();
            for (int c = 0; c < Iteration_Results.Count; c++)
            {
                for (int i = 0; i < Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results.Count; i++)
                {
                    if (tDic.ContainsKey(Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle) == false)
                        tDic.Add(Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle, new double[Iteration_Results.Count]);

                    tDic[Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle][c] =
                        Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Match_Score;
                }
            }

            using (StreamWriter overviewResultsWriter = new StreamWriter(exp_rq[0] + "\\Reasoning Results\\Overview.txt"))
            {
                overviewResultsWriter.WriteLine("Rotation Angle\tMatch Score");

                foreach (var item in tDic)
                {
                    string line = item.Key.ToString() + "\t";
                    for (int lngth = 0; lngth < item.Value.Length; lngth++)
                    {
                        if (item.Value[lngth] != 0) line += Math.Round(item.Value[lngth], 2).ToString();
                        line += "\t";
                    }
                    line = line.Remove(line.Length - 1);
                    overviewResultsWriter.WriteLine(line);
                }
            }

            #endregion

            #region -_-            Print Gamma Fig A            -_-

            if (exp_rq[2] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Gamma\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Gamma\\");

                for (int c = 0; c < Iteration_Results.Count; c++)
                {
                    using (
                        StreamWriter Fig_A =
                            new StreamWriter(
                                exp_rq[0] +
                                "\\Gamma\\" + Figures_Name[0] + " [L-" + (Omega + c).ToString() + "].txt"))
                    {

                        for (
                            int i = 0;
                            i < Engine[Compared_Figs_DG.SelectedIndex].
                            Iterations[c].Fig_A_Gamma.Count;
                            i++)
                        {
                            string t = "";

                            for (int j = 0; j < Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Fig_A_Gamma[i].Count; j++)
                                t += Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Fig_A_Gamma[i][j] + "\t";

                            Fig_A.WriteLine(t);
                        }
                    }
                }
            }
            #endregion

            #region -_-            Print Gamma Fig B            -_-

            if (exp_rq[2] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Gamma\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Gamma\\");

                for (int c = 0; c < Iteration_Results.Count; c++)
                {
                    using (
                        StreamWriter Fig_B =
                            new StreamWriter(
                                exp_rq[0] +
                                "\\Gamma\\" + Figures_Name[1] + " [L-" + (Omega + c).ToString() + "].txt"))
                    {

                        for (
                            int i = 0;
                            i < Engine[Compared_Figs_DG.SelectedIndex].
                            Iterations[c].Fig_B_Gamma.Count;
                            i++)
                        {
                            string t = "";

                            for (int j = 0; j < Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Fig_B_Gamma[i].Count; j++)
                                t += Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Fig_B_Gamma[i][j] + "\t";

                            Fig_B.WriteLine(t);
                        }
                    }
                }
            }
            #endregion

            #region -_-             Print Alpha set             -_-

            if (exp_rq[3] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Alpha\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Alpha\\");

                for (int c = 0; c < Iteration_Results.Count; c++)
                {
                    using (
                        StreamWriter Alpha =
                            new StreamWriter(
                                exp_rq[0] +
                                "\\Alpha\\Alpha" + " [L-" + (Omega + c).ToString() + "].txt"))
                    {
                        string t = "";

                        for (
                            int i = 0;
                            i < Engine[Compared_Figs_DG.SelectedIndex].
                            Iterations[c].Alpha.Count;
                            i++)
                        {
                            t += Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Alpha[i].ToString() + "\t";
                            Alpha.WriteLine(Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Alpha[i].ToString() + "\t");
                        }
                    }
                }
            }
            #endregion

            #region -_-          Print Landmark Point           -_-

            if (exp_rq[4] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Landmark Points\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Landmark Points\\");

                using (
                    StreamWriter LandMark_A =
                        new StreamWriter(
                            exp_rq[0] +
                            "\\Landmark Points\\Alpha" + Figures_Name[0] + "[ Landmarks ].txt"))
                {
                    for (int y = 0; y < max_y; y++)
                    {
                        string l = "";
                        for (int x = 0; x < max_x; x++)
                            if (Engine[Compared_Figs_DG.SelectedIndex].Figure_A[x][y] == true)
                                l += "1\t";
                            else
                                l += "0\t";

                        LandMark_A.WriteLine(l);
                    }
                }

                using (
                    StreamWriter LandMark_B =
                        new StreamWriter(
                            exp_rq[0] +
                            "\\Landmark Points\\Alpha" + Figures_Name[1] + "[ Landmarks ].txt"))
                {
                    for (int y = 0; y < max_y; y++)
                    {
                        string l = "";
                        for (int x = 0; x < max_x; x++)
                            if (Engine[Compared_Figs_DG.SelectedIndex].Figure_B[x][y] == true)
                                l += "1\t";
                            else
                                l += "0\t";

                        LandMark_B.WriteLine(l);
                    }
                }

            }
            #endregion

            #region -_-            Print Differences            -_-

            if (exp_rq[5] == "1")
            {
                if (!Directory.Exists(exp_rq[0]))
                    Directory.CreateDirectory(exp_rq[0]);

                if (!Directory.Exists(exp_rq[0] + "\\Differences\\"))
                    Directory.CreateDirectory(exp_rq[0] + "\\Differences\\");

                using (
                    StreamWriter Differences_SW =
                        new StreamWriter(exp_rq[0] + "\\Differences\\Differences.txt"))
                {
                    #region -_-        Difference among top 2        -_-

                    string
                        t_Line = "Difference among Top 2",
                        h_Line = "Type";

                    for (int l = 0; l < Engine[Compared_Figs_DG.SelectedIndex].Iterations.Count; l++)
                    {
                        h_Line += "\tl = " + (l + Engine[Compared_Figs_DG.SelectedIndex].Omega).ToString();

                        t_Line +=
                            "\t" +
                            (Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[0].Match_Score -
                            Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[1].Match_Score).ToString();
                    }

                    Differences_SW.WriteLine(h_Line);
                    Differences_SW.WriteLine(t_Line);

                    #endregion

                    #region -_-    Standard Deviation among top 10   -_-

                    t_Line = "Standard deviation among top 10";

                    for (int l = 0; l < Engine[Compared_Figs_DG.SelectedIndex].Iterations.Count; l++)
                    {
                        int max_results = 0;
                        if (Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count < 10)
                            max_results = Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count;
                        else max_results = 10;

                        double
                            t_Sum = 0.0,
                            t_Avr = 0.0,
                            t_SRM = 0.0;

                        for (int i = 0; i < max_results; i++)
                        {
                            t_Sum += Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[i].Match_Score;
                        }

                        t_Avr = t_Sum / (double)max_results;

                        for (int i = 0; i < max_results; i++)
                        {
                            t_SRM += Math.Pow(Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[i].Match_Score - t_Avr, 2);
                        }

                        t_Line += "\t" +
                            Math.Pow(t_SRM / max_results, 0.5);
                    }

                    Differences_SW.WriteLine(t_Line);

                    #endregion

                    #region -_- Standard Deviation among all results -_-

                    t_Line = "Standard deviation among all results";

                    for (int l = 0; l < Engine[Compared_Figs_DG.SelectedIndex].Iterations.Count; l++)
                    {
                        double
                            t_Sum = 0.0,
                            t_Avr = 0.0,
                            t_SRM = 0.0;

                        for (int i = 0; i < Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count; i++)
                        {
                            t_Sum += Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[i].Match_Score;
                        }

                        t_Avr = t_Sum / (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count;

                        for (int i = 0; i < Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count; i++)
                        {
                            t_SRM += Math.Pow(Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results[i].Match_Score - t_Avr, 2);
                        }

                        t_Line += "\t" +
                            Math.Pow(t_SRM / Engine[Compared_Figs_DG.SelectedIndex].Iterations[l].Results.Count, 0.5);
                    }

                    Differences_SW.WriteLine(t_Line);

                    #endregion
                }
            }
            #endregion

            #region -_-      Print Normalized Distribution      -_-

            if (!Directory.Exists(exp_rq[0]))
                Directory.CreateDirectory(exp_rq[0]);

            if (!Directory.Exists(exp_rq[0] + "\\Gamma values distribution\\"))
                Directory.CreateDirectory(exp_rq[0] + "\\Gamma values distribution\\");

            for (int c = 0; c < Iteration_Results.Count; c++)
            {
                using (StreamWriter sw = new StreamWriter(exp_rq[0] + "\\Gamma values distribution\\" + Figures_Name[0] + " [L-" + (Omega + c).ToString() + "].txt"))
                {
                    sw.WriteLine("GammaValue\tFrequency");
                    foreach (var item in Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Figure_A_landmarkDistribution)
                        sw.WriteLine(item.Key + "\t" + item.Value);
                }
                using (StreamWriter sw = new StreamWriter(exp_rq[0] + "\\Gamma values distribution\\" + Figures_Name[1] + " [L-" + (Omega + c).ToString() + "].txt"))
                {
                    sw.WriteLine("GammaValue\tFrequency");
                    foreach (var item in Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Figure_B_landmarkDistribution)
                        sw.WriteLine(item.Key + "\t" + item.Value);
                }
            }

            #endregion
        }


        // Functions Required for Load Process
        // Reset All parameters to default values
        private void Reset_for_new_Start()
        {
            SCV = true;
            Initialize_temp_Matrix();
            Process_and_Details_Tab.SelectedIndex = 0;
            Figures_DG.Items.Clear();
            Figures_DG.Columns.Clear();
            number_of_drawn_figures = 0;
            Figures_Name.Clear();
            Figures.Clear();
            Engine.Clear();
            Compared_Figs_DG.Items.Clear();
            Compared_Figs_DG.Columns.Clear();

            Iteration_Results.Clear();
            Data_Alpha_Set.Clear();
            Data_Gamma_Set.Clear();
            Data_Results.Clear();

            Iterations_DG.Columns.Clear();
            Results_DG.Columns.Clear();

            Reset_Timers();

            Results_DG.Columns.Clear();

            Iteration_index_to_be_Shown = 0;

            Last_turned_on_Pixels_for_preview = 0;

            Instant_Progress_Step_Apply.IsChecked = true;
            Progress_Step_Size_Slider.Value = 1;
            Progress_Step_Size_L.Text = "Progress Step Size : 1";
            
            GammaContents_RB.IsEnabled = false;
            GammaDistribution_RB.IsEnabled = false;
            Level_result.IsEnabled = false;
            Alpha_set_RB.IsEnabled = false;
            Level_result_graph.IsEnabled = false;
            All_result_graph.IsEnabled = false;

            Illustrate_Transformation_L.IsEnabled = false;
            Segmentation_Chart_L.IsEnabled = false;

            Alpha_set_RB.IsChecked = true;

            d = Default_d;
            Omega = Default_Omega;
            Lambda = Default_Lambda;
            Upsilon = Default_Upsilon;
            Epsilon = Default_Epsilon;

            Omega_TB.Text = Default_Omega.ToString();
            Lambda_TB.Text = Default_Lambda.ToString();
            Upsilon_TB.Text = Default_Upsilon.ToString();
            Epsilon_TB.Text = Default_Epsilon.ToString() + ".00";
            Max_L_4_chosen_Epsilon.Content =
                        "Max L =  " +
                        Math.Ceiling(Math.Log((360 / Epsilon), 2)).ToString();

            while (Chart.Children.Count > 12)
                Chart.Children.RemoveAt(Chart.Children.Count - 1);

            Draw_PFR_L.Visibility = Visibility.Hidden;
            Draw_Random_Points_L.Visibility = Visibility.Hidden;
            Draw_Line_or_Circle_L.Visibility = Visibility.Hidden;

            FSH_TB.Focusable = true;
            FSW_TB.Focusable = true;

            #region Clear all current pixels            

            Set_New_Figure_Canvas_Size();
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                    temp_Matrix[x][y] = false;

            Preview_Pixels.Clear();
            Draw_Preview_Pixels();

            #endregion

            SCV = false;
        }
        private void Create_Drawn_Figures()
        {
            for (int i = 0; i < Figures.Count; i++)
            {
                DataContext = new List<Figurez>
            {
                new Figurez
                {
                    Figure_ID = "Fig " + i.ToString(),
                    Figure_Name = Figures_Name[i]
                }
            };
                Figures_DG.Items.Add(new Figurez
                {
                    Figure_ID = "Fig " + i.ToString(),
                    Figure_Name = Figures_Name[i]

                });
            }

            Figures_DG.Columns.Add(new DataGridTextColumn { Header = "ID", Binding = new Binding("Figure_ID"), Width = 40, MinWidth = 40 });
            Figures_DG.Columns.Add(new DataGridTextColumn { Header = "Lable", Binding = new Binding("Figure_Name"), Width = new DataGridLength(100, DataGridLengthUnitType.Star), MinWidth = 130 });
        }


        // A Drawn Figure is selected and choose for preview 
        private void Figures_DG_Loaded(object sender, RoutedEventArgs e)
        {
            //Figures_DG.Height = Figures_DG_Canvas.Height - 10;
        }
        private void Figures_DG_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (Figures_DG.SelectedIndex != -1)
            {
                Set_reView_Canvas_Size();
                reView_Figure(Figures_DG.SelectedIndex);
            }
        }
        private void Set_reView_Canvas_Size()
        {
            double Ratio = (double)max_x / (double)max_y;

            if (Process_and_Details_Tab.ActualWidth > Process_and_Details_Tab.ActualHeight - 150)
            {
                // Set ratio based on Width
                reView_Canvas.Height = Process_and_Details_Tab.ActualHeight - 150;
                reView_Canvas.Width = Ratio * (Process_and_Details_Tab.ActualHeight - 150);
            }
            else
            {
                // Set ratio based on Height
                reView_Canvas.Width = Process_and_Details_Tab.ActualWidth;
                reView_Canvas.Height = Process_and_Details_Tab.ActualWidth / Ratio;
            }
        }
        private void reView_Figure(int Figure_number)
        {
            Process_and_Details_Tab.SelectedIndex = 2;

            Color onColor = Colors.OrangeRed;
            Color offColor = Colors.Black;

            List<Color> colors = new List<Color>();
            colors.Add(onColor);
            colors.Add(offColor);
            BitmapPalette palette = new BitmapPalette(colors);
            PixelFormat pixelFormat = PixelFormats.Bgra32;

            int stride = max_x * 4;
            
            byte[] pixels = new byte[max_y * stride];
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                {
                    if (Figures[Figure_number][x][y] == true)
                    {
                        pixels[(x * 4) + (y * stride) + 0] = onColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = onColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = onColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = onColor.A;
                    }
                    else
                    {
                        pixels[(x * 4) + (y * stride) + 0] = offColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = offColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = offColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = offColor.A;
                    }
                }


            var bitmap = BitmapSource.Create(max_x, max_y, 96, 96, pixelFormat, palette, pixels, stride);
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = bitmap;
            reView_Canvas.Background = ib;
            
            Rectangle Grid_Outline = new Rectangle();
            Grid_Outline.Width = reView_Canvas.Width;
            Grid_Outline.Height = reView_Canvas.Height;
            Grid_Outline.Fill = new SolidColorBrush(Colors.Transparent);
            Grid_Outline.Stroke = new SolidColorBrush(Colors.OrangeRed);
            Grid_Outline.StrokeThickness = 4;
            reView_Canvas.Children.Add(Grid_Outline);
            Canvas.SetTop(Grid_Outline, 0);
            Canvas.SetLeft(Grid_Outline, 0);
        }


        // Return button at review page
        private void Back_to_reasoning_process_MouseEnter(object sender, MouseEventArgs e)
        {
            Back_to_reasoning_process.Foreground = Button_Mouse_Enter_Color;
        }
        private void Back_to_reasoning_process_MouseLeave(object sender, MouseEventArgs e)
        {
            Back_to_reasoning_process.Foreground = Button_Mouse_Leave_Color;
        }
        private void Back_to_reasoning_process_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Process_and_Details_Tab.SelectedIndex = 0;
        }


        // Run Reasoning button
        private void Run_Reasoning_BT_MouseEnter(object sender, MouseEventArgs e)
        {
            Run_Reasoning_BT.Foreground = Button_Mouse_Enter_Color;
        }
        private void Run_Reasoning_BT_MouseLeave(object sender, MouseEventArgs e)
        {
            Run_Reasoning_BT.Foreground = Button_Mouse_Leave_Color;
        }
        private void Run_Reasoning_BT_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Reset_Timers();

            DT_Reasoning_Run_Time.Start();

            Process_and_Details_Tab.SelectedIndex = 0;
            Figure_A_index = -1;
            Figure_B_index = 0;
            Engine_index = -1;

            #region Reset Parameters
            Iteration_Results.Clear();
            Data_Alpha_Set.Clear();
            Data_Gamma_Set.Clear();
            Data_Results.Clear();

            Iterations_DG.Columns.Clear();
            Results_DG.Columns.Clear();

            Reset_Timers();

            Results_DG.Columns.Clear();

            Iteration_index_to_be_Shown = 0;

            Last_turned_on_Pixels_for_preview = 0;
            #endregion

            Engine.Clear();

            Run_Next_Pair_Reasoning();
        }        

        #endregion



        #region -_-                   Preferences                      -_-

        private void Omega_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Omega_TB.SelectAll();
        }
        private void Lambda_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Lambda_TB.SelectAll();
        }
        private void Upsilon_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Upsilon_TB.SelectAll();
        }
        private void Epsilon_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Epsilon_TB.SelectAll();
        }
        private void Constant_Neighbor_C_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Constant_Neighbor_C_TB.SelectAll();
        }

        private void d_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void Omega_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void Lambda_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void Upsilon_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void Epsilon_TB_KeyDown(object sender, KeyEventArgs e)
        {
            bool Is_OemPeriod_already_entered = false;
            for (int i = 0; i < Epsilon_TB.Text.Length; i++)
                if (Epsilon_TB.Text[i] == '.')
                    Is_OemPeriod_already_entered = true;

            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.OemPeriod:
                case Key.Decimal:
                    e.Handled = Is_OemPeriod_already_entered;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void Constant_Neighbor_C_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }


        private void Omega_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (Omega_TB != null &&
                SCV == false)
            {
                SCV = true;

                Omega_TB.Text = Omega_TB.Text.Trim();

                if (Omega_TB.Text.Trim() != "")
                {
                    Omega_TB.Text = (Convert.ToInt32(Omega_TB.Text)).ToString();

                    Omega = Convert.ToInt32(Omega_TB.Text);

                    Omega_TB.SelectionStart = Omega_TB.Text.Length;
                }                

                SCV = false;
            }
        }
        private void Lambda_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (Lambda_TB != null &&
                SCV == false)
            {
                SCV = true;

                Lambda_TB.Text = Lambda_TB.Text.Trim();

                if (Lambda_TB.Text.Trim() != "")
                {
                    Lambda_TB.Text = (Convert.ToInt32(Lambda_TB.Text)).ToString();

                    Lambda = Convert.ToInt32(Lambda_TB.Text);

                    Lambda_TB.SelectionStart = Lambda_TB.Text.Length;
                }

                SCV = false;
            }
        }
        private void Upsilon_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (Upsilon_TB != null &&
                SCV == false)
            {
                SCV = true;

                Upsilon_TB.Text = Upsilon_TB.Text.Trim();

                if (Upsilon_TB.Text.Trim() != "")
                {
                    Upsilon_TB.Text = (Convert.ToInt32(Upsilon_TB.Text)).ToString();

                    Upsilon = Convert.ToInt32(Upsilon_TB.Text);

                    Upsilon_TB.SelectionStart = Upsilon_TB.Text.Length;
                }

                SCV = false;
            }
        }
        private void Epsilon_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (Max_L_4_chosen_Epsilon != null &&
                Epsilon_TB != null &&
                SCV == false)
            {
                SCV = true;

                Epsilon_TB.Text = Epsilon_TB.Text.Trim();

                if (Epsilon_TB.Text.Trim() != "" &&
                    Epsilon_TB.Text.Trim() != ".")
                {
                    Max_L_4_chosen_Epsilon.Content =
                        "Max L =  " +
                        Math.Ceiling(Math.Log((360 / Convert.ToDouble(Epsilon_TB.Text)), 2)).ToString();

                    Epsilon = Convert.ToDouble(Epsilon_TB.Text);

                    Epsilon_TB.SelectionStart = Epsilon_TB.Text.Length;
                }

                SCV = false;
            }
        }
        private void Constant_Neighbor_C_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (Constant_Neighbor_C_TB != null &&
                            SCV == false)
            {
                SCV = true;

                Constant_Neighbor_C_TB.Text = Constant_Neighbor_C_TB.Text.Trim();

                if (Constant_Neighbor_C_TB.Text.Trim() != "")
                {
                    Constant_Neighbor_C_TB.Text = (Convert.ToInt32(Constant_Neighbor_C_TB.Text)).ToString();

                    Constant_Neighbor_C_TB.SelectionStart = Constant_Neighbor_C_TB.Text.Length;
                }

                SCV = false;
            }
        }


        private void Omega_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            if (Omega_TB.Text == "")
            {
                SCV = true;

                Omega_TB.Text = Default_Omega.ToString();
                Omega = Default_Omega;

                SCV = false;
            }
        }
        private void Lambda_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            if (Lambda_TB.Text == "")
            {
                SCV = true;

                Lambda_TB.Text = Default_Lambda.ToString();

                Lambda = Default_Lambda;

                SCV = false;
            }
        }
        private void Upsilon_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            if (Upsilon_TB.Text == "")
            {
                SCV = true;

                Upsilon_TB.Text = Default_Upsilon.ToString();

                Upsilon = Default_Upsilon;

                SCV = false;
            }
        }
        private void Epsilon_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            if (Epsilon_TB.Text.Trim() != "" &&
                    Epsilon_TB.Text.Trim() != ".")
            {
                SCV = true;

                Epsilon_TB.Text = (Convert.ToDouble(Epsilon_TB.Text)).ToString();

                SCV = false;
            }
            else
            {
                SCV = true;

                Epsilon = Default_Epsilon;

                Epsilon_TB.Text = Default_Epsilon.ToString() + ".00";

                Max_L_4_chosen_Epsilon.Content =
                        "Max L =  " +
                        Math.Ceiling(Math.Log((360 / Epsilon), 2)).ToString();

                SCV = false;
            }
        }
        private void Constant_Neighbor_C_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            if (Constant_Neighbor_C_TB.Text == "")
            {
                SCV = true;

                Constant_Neighbor_C_TB.Text = "2";

                SCV = false;
            }
        }


        private void Process_Neighbors_Checked(object sender, RoutedEventArgs e)
        {
            if (Akin_2_Iteration != null &&
                Constant_Neighbor_RB != null &&
                Constant_Neighbor_C_TB != null)
            {
                Akin_2_Iteration.IsChecked = true;
                Akin_2_Iteration.IsEnabled = true;
                Constant_Neighbor_RB.IsEnabled = true;
                Constant_Neighbor_RB.IsChecked = false;
                Constant_Neighbor_C_TB.IsReadOnly = true;
            }
        }
        private void Process_Neighbors_Unchecked(object sender, RoutedEventArgs e)
        {
            if (Akin_2_Iteration != null &&
                Constant_Neighbor_RB != null &&
                Constant_Neighbor_C_TB != null)
            {
                Akin_2_Iteration.IsEnabled = false;
                Constant_Neighbor_RB.IsEnabled = false;
                Constant_Neighbor_C_TB.IsReadOnly = true;
            }
        }


        private void Constant_Neighbor_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (Constant_Neighbor_C_TB != null)
                Constant_Neighbor_C_TB.IsReadOnly = false;
        }
        private void Constant_Neighbor_RB_Unchecked(object sender, RoutedEventArgs e)
        {
            if (Constant_Neighbor_C_TB != null)
                Constant_Neighbor_C_TB.IsReadOnly = true;
        }

        #endregion



        #region -_-                Reasoning Overview                  -_-

        // Compared figures DataGrid selectoin change
        private void Compared_Figs_DG_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (SCV == false)
                if (Compared_Figs_DG.SelectedIndex != -1)
                {
                    Engine_index = Compared_Figs_DG.SelectedIndex;
                    //Show_Reasoing_Results();
                }
                else
                {
                    Engine_index = 0;
                    Compared_Figs_DG.SelectedIndex = 0;
                    //Show_Reasoing_Results();
                }
        }


        // Selected Iteration Changed
        private void Iterations_DG_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (Iterations_DG.SelectedIndex != -1)
            {
                Iteration_index_to_be_Shown = Iterations_DG.SelectedIndex;
                Show_Reasoing_Results();
            }
        }


        // View Option Changed
        private void GammaContents_RB_Checked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 2;
            Show_Reasoing_Results();
        }
        private void GammaDistribution_RB_Checked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 3;
            Show_Reasoing_Results();
        }
        private void Level_result_Checked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 4;
            Show_Reasoing_Results();
        }
        private void Alpha_set_RB_Checked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 1;
            Show_Reasoing_Results();
        }
        private void Level_result_graph_Checked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 5;
            Show_Reasoing_Results();
        }
        private void All_result_graph_Checked(object sender, RoutedEventArgs e)
        {
            All_result_graph.IsChecked = true;
            Type_of_Data_to_show = 6;
            Show_Reasoing_Results();
        }
        private void LogarithmicAllResultsPlot_Checked(object sender, RoutedEventArgs e)
        {
            All_result_graph.IsChecked = true;
            Type_of_Data_to_show = 6;
            Show_Reasoing_Results();
        }
        private void LogarithmicAllResultsPlot_Unchecked(object sender, RoutedEventArgs e)
        {
            Type_of_Data_to_show = 6;
            Show_Reasoing_Results();
        }
        // Results DataGrid double-clicked 
        private void Results_DG_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (Results_DG.SelectedIndex != -1)
            {
                if (Level_result.IsChecked == true)
                {
                    Prepare_Illustration();
                }
                else
                {
                    Process_and_Details_Tab.SelectedIndex = 5;

                    My_Chart_Fig_A(
                        Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma);

                    My_Chart_Fig_B(
                        Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_B_Gamma);
                }
            }
        }
        // Show selected reasoning results
        private void Show_Reasoing_Results()
        {
            if (Compared_Figs_DG != null && SCV == false)
            {
                int i_Max = 0;

                Results_DG.Columns.Clear();
                Data_Alpha_Set.Clear();
                Data_Gamma_Set.Clear();
                Data_Results.Clear();

                int N = 0, M = 0, index_Counter = 0;

                #region Common Styling parameters definition
                Style Cell_Style = new System.Windows.Style(typeof(DataGridCell));


                Cell_Style.Setters.Add(
                    new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center));

                Cell_Style.Setters.Add(
                    new Setter(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center));

                DataGridTextColumn Index_c = new DataGridTextColumn();
                Index_c.Header = "Index";
                Index_c.Binding = new Binding("index");
                Index_c.Width = 50;
                Index_c.CellStyle = Cell_Style;

                DataGridTextColumn Value_C = new DataGridTextColumn();
                Value_C.Header = "Landmark points count";
                Value_C.Binding = new Binding("Value");
                Value_C.Width = 140;
                Value_C.CellStyle = Cell_Style;

                DataGridTextColumn C_Shift_C = new DataGridTextColumn();
                C_Shift_C.Binding = new Binding("C_Shift");
                C_Shift_C.Width = 160;
                C_Shift_C.CellStyle = Cell_Style;

                DataGridTextColumn C_Rotation_C = new DataGridTextColumn();
                C_Rotation_C.Header = "Corresponding Rotation Angle";
                C_Rotation_C.Binding = new Binding("Corresponding_Rotation_Angle");
                C_Rotation_C.Width = 160;
                C_Rotation_C.CellStyle = Cell_Style;
                #endregion

                switch (Type_of_Data_to_show)
                {
                    case 1:
                        #region Show Alpha set of given iteration

                        Re_Gr_Tab.SelectedIndex = 0;

                        Results_DG.ItemsSource = Data_Alpha_Set;

                        #region Columns Definitions
                        C_Shift_C.Header = "Members of Alpha set (Circular Shift steps)";
                        C_Shift_C.Width = 280;
                        C_Rotation_C.Width = 180;

                        Results_DG.Columns.Add(Index_c);
                        Results_DG.Columns.Add(C_Shift_C);
                        Results_DG.Columns.Add(C_Rotation_C);
                        #endregion

                        int Alpha_set_Count =
                            Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Alpha.Count;

                        double Segment_Size =
                            360 / Math.Pow(2,
                            Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].LN);

                        for (int i = 0; i < Alpha_set_Count; i++)
                        {
                            Data_Alpha_Set.Add(new Alpha_Details()
                            {
                                index = i,
                                C_Shift =
                                Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Alpha[i],
                                Corresponding_Rotation_Angle = Math.Abs(
                                (double)
                                (Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Alpha[i] * Segment_Size) - 360)
                            });
                        }
                        #endregion
                        break;

                    case 2:
                        #region Show Gamma content in given iteration

                        Re_Gr_Tab.SelectedIndex = 0;

                        Results_DG.ItemsSource = Data_Gamma_Set;

                        #region Columns Definitions
                        DataGridTextColumn N_C_A = new DataGridTextColumn();
                        N_C_A.Header = "N";
                        N_C_A.Binding = new Binding("N");
                        N_C_A.Width = 100;
                        N_C_A.CellStyle = Cell_Style;

                        DataGridTextColumn M_C_A = new DataGridTextColumn();
                        M_C_A.Header = "M";
                        M_C_A.Binding = new Binding("M");
                        M_C_A.Width = 100;
                        M_C_A.CellStyle = Cell_Style;

                        DataGridTextColumn Value_FigA = new DataGridTextColumn();
                        Value_FigA.Header = "Figure A";
                        Value_FigA.Binding = new Binding("FigAValue");
                        Value_FigA.Width = 100;
                        Value_FigA.CellStyle = Cell_Style;

                        DataGridTextColumn Value_FigB = new DataGridTextColumn();
                        Value_FigB.Header = "Figure B";
                        Value_FigB.Binding = new Binding("FigBValue");
                        Value_FigB.Width = 100;
                        Value_FigB.CellStyle = Cell_Style;

                        Results_DG.Columns.Add(Index_c);
                        Results_DG.Columns.Add(N_C_A);
                        Results_DG.Columns.Add(M_C_A);
                        Results_DG.Columns.Add(Value_FigA);
                        Results_DG.Columns.Add(Value_FigB);
                        #endregion

                        N = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma.Count;
                        M = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma[0].Count;
                        var FigAGamma = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma;
                        var FigBGamme = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_B_Gamma;
                        index_Counter = 0;

                        for (int n = 0; n < N; n++)
                            for (int m = 0; m < M; m++)
                            {
                                index_Counter++;
                                Data_Gamma_Set.Add(new Gamma_Details()
                                {
                                    index = index_Counter,
                                    N = n,
                                    M = m,
                                    FigAValue = FigAGamma[n][m],
                                    FigBValue = FigBGamme[n][m],
                                    Value =
                                    Engine[Compared_Figs_DG.SelectedIndex].
                                    Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma[n][m]
                                });
                            }
                        #endregion
                        break;

                    case 3:
                        #region Show Gamme distribution on given iteration on Graph

                        while (Chart.Children.Count > 12)
                            Chart.Children.RemoveAt(Chart.Children.Count - 1);

                        Re_Gr_Tab.SelectedIndex = 1;

                        #region Read Results into corresponding list

                        var c3PointsA = new List<Point>();
                        foreach (var item in Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Figure_A_landmarkDistribution)
                            c3PointsA.Add(new Point(x: item.Key, y: Math.Log10(item.Value)));

                        var c3PointsB = new List<Point>();
                        foreach (var item in Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Figure_B_landmarkDistribution)
                            c3PointsB.Add(new Point(x: item.Key, y: Math.Log10(item.Value)));

                        #endregion

                        var c3PDSA = new EnumerableDataSource<Point>(c3PointsA);
                        c3PDSA.SetXMapping(x => x.X);
                        c3PDSA.SetYMapping(y => y.Y);

                        var c3PDSB = new EnumerableDataSource<Point>(c3PointsB);
                        c3PDSB.SetXMapping(x => x.X);
                        c3PDSB.SetYMapping(y => y.Y);

                        Chart.AddLineGraph(
                                c3PDSA,
                                new Pen(new SolidColorBrush(Colors.OrangeRed), 0.5),
                                new CirclePointMarker { Size = 10, Fill = new SolidColorBrush(Colors.OrangeRed) },
                                new PenDescription((string)Iteration_Results[Iteration_index_to_be_Shown].Title + "   Figure A Gamma Distribution  "));

                        Chart.AddLineGraph(
                                c3PDSB,
                                new Pen(new SolidColorBrush(Colors.Lime), 0.5),
                                new TrianglePointMarker { Size = 10, Fill = new SolidColorBrush(Colors.Lime) },
                                new PenDescription((string)Iteration_Results[Iteration_index_to_be_Shown].Title + "   Figure B Gamma Distribution  "));

                        HorizontalAxisTitle.Content = "\nGamma Value";
                        VerticalAxisTitle.Content = "Frequency (logarithmic)\n";
                        #endregion
                        break;

                    case 4:
                        #region Show compare Results of given iteration

                        Re_Gr_Tab.SelectedIndex = 0;

                        Results_DG.ItemsSource = Data_Results;

                        #region Columns Definitions
                        DataGridTextColumn Match_Ration_C = new DataGridTextColumn();
                        Match_Ration_C.Header = "Match Ratio";
                        Match_Ration_C.Binding = new Binding("Match_Ratio");
                        Match_Ration_C.Width = 140;
                        Match_Ration_C.CellStyle = Cell_Style;

                        DataGridTextColumn LMP_C = new DataGridTextColumn();
                        LMP_C.Header = "Matched Landmarks";
                        LMP_C.Binding = new Binding("Matched_Landmarks");
                        LMP_C.Width = 160;
                        LMP_C.CellStyle = Cell_Style;

                        DataGridTextColumn MS_C = new DataGridTextColumn();
                        MS_C.Header = "Matched Regions";
                        MS_C.Binding = new Binding("Matched_Regions");
                        MS_C.Width = 160;
                        MS_C.CellStyle = Cell_Style;

                        C_Shift_C.Header = "Proper {Alpha} Members";

                        Results_DG.Columns.Add(Index_c);
                        Results_DG.Columns.Add(Match_Ration_C);
                        Results_DG.Columns.Add(C_Rotation_C);
                        Results_DG.Columns.Add(C_Shift_C);
                        Results_DG.Columns.Add(LMP_C);
                        Results_DG.Columns.Add(MS_C);
                        #endregion

                        N = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_B_Gamma.Count;
                        M = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_B_Gamma[0].Count;
                        index_Counter = 0;

                        i_Max = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results.Count;

                        for (int i = 0; i < i_Max; i++)
                        {
                            /*
                            double Match_Score =
                                (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Match_Score;*/

                            index_Counter++;
                            Data_Results.Add(new Results_Details()
                            {
                                index = index_Counter,
                                Match_Ratio = Math.Round(Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Match_Score, 8), //Match_Score,
                                C_Shift = (int)Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].C_Shitfs,
                                Corresponding_Rotation_Angle = (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Rotation_Angle,

                                Matched_Landmarks =
                                (Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Matched_Landmarks_Count).ToString() + "  ( " +
                                (Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Matched_Landmarks_Ratio).ToString() + " % )",

                                Matched_Regions =
                                (Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Matched_Regions).ToString() + "  ( " +
                                (Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Matched_Regions_Ratio).ToString() + " % )"
                            });
                        }
                        #endregion
                        break;

                    case 5:
                        #region Show compare Results on given iteration on Graph

                        while (Chart.Children.Count > 12)
                            Chart.Children.RemoveAt(Chart.Children.Count - 1);

                        Re_Gr_Tab.SelectedIndex = 1;

                        #region Read Results into corresponding list

                        i_Max = Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results.Count;

                        var c5PointsA = new List<Point>();
                        for (int i = 0; i < i_Max; i++)
                        {
                            c5PointsA.Add(new Point()
                            {
                                X =
                                (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Rotation_Angle,

                                Y =
                                Math.Round(Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Results[i].Match_Score, 8)
                            });
                        }

                        #endregion

                        var c5PDSA = new EnumerableDataSource<Point>(c5PointsA);
                        c5PDSA.SetXMapping(x => x.X);
                        c5PDSA.SetYMapping(y => y.Y);

                        Chart.AddLineGraph(
                                c5PDSA,
                                new Pen(new SolidColorBrush(Colors.Black), 0),
                                new CirclePointMarker { Size = 12, Fill = new SolidColorBrush(Color.FromArgb(255,0,255,255)) },
                                new PenDescription((string)Iteration_Results[Iteration_index_to_be_Shown].Title + "   Reasoning Results  "));

                        HorizontalAxisTitle.Content = "\nRotation Angles";
                        VerticalAxisTitle.Content = "Match Score\n";
                        #endregion
                        break;

                    case 6:
                        #region Show compare Results of all the iterations in a graph

                        while (Chart.Children.Count > 12)
                            Chart.Children.RemoveAt(Chart.Children.Count - 1);

                        Re_Gr_Tab.SelectedIndex = 1;
                        

                        #region Read Results into corresponding list

                        for (int c = 0; c < Engine[Compared_Figs_DG.SelectedIndex].Iterations.Count; c++)
                        {
                            i_Max = Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results.Count;

                            var c6Points = new List<Point>();
                            if (LogarithmicAllResultsPlot.IsChecked == true)                            
                                for (int i = 0; i < i_Max; i++)
                                    c6Points.Add(new Point()
                                    {
                                        X =
                                        (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle,

                                        Y =
                                        Math.Log10(Math.Round(Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Match_Score, 8))
                                    });
                            else
                                for (int i = 0; i < i_Max; i++)
                                    c6Points.Add(new Point()
                                    {
                                        X =
                                        (double)Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Rotation_Angle,

                                        Y =
                                        Math.Round(Engine[Compared_Figs_DG.SelectedIndex].Iterations[c].Results[i].Match_Score, 8)
                                    });



                            c6Points.Sort(new Point_Comparer());

                            var c6PDS = new EnumerableDataSource<Point>(c6Points);
                            c6PDS.SetXMapping(x => x.X);
                            c6PDS.SetYMapping(y => y.Y);

                            byte[] C = aIGC(c);

                            Chart.AddLineGraph(
                                    c6PDS,
                                    new Pen(new SolidColorBrush(Color.FromArgb(255, C[0], C[1], C[2])), 0.5),
                                    new CirclePointMarker { Size = 8, Fill = new SolidColorBrush(Color.FromArgb(255, C[0], C[1], C[2])) },
                                    new PenDescription((string)Iteration_Results[c].Title + "   Reasoning Results  "));

                            HorizontalAxisTitle.Content = "\nRotation Angles";
                            VerticalAxisTitle.Content = "Match Score\n";
                        }



                        #endregion
                        #endregion
                        break;
                }
            }
        }


        // Illustrate transformation lable
        private void Illustrate_Transformation_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Illustrate_Transformation_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Illustrate_Transformation_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Illustrate_Transformation_L.Foreground = Button_Mouse_Leave_Color;
        }
        private void Illustrate_Transformation_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Prepare_Illustration();
        }


        // Illustrate Segmentation Chart lable
        private void Segmentation_Chart_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Segmentation_Chart_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Segmentation_Chart_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Segmentation_Chart_L.Foreground = Button_Mouse_Leave_Color;
        }
        private void Segmentation_Chart_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Process_and_Details_Tab.SelectedIndex = 4;

            My_Chart_Fig_A(
                Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_A_Gamma);

            My_Chart_Fig_B(
                Engine[Compared_Figs_DG.SelectedIndex].Iterations[Iteration_index_to_be_Shown].Fig_B_Gamma);
        }

        public class Point_Comparer : IComparer<Point>
        {
            public int Compare(Point A, Point B)
            {
                if (A == null)
                {
                    if (B == null)
                    {
                        // then they are equal
                        return 0;
                    }
                    else
                    {
                        // then B is greater
                        return -1;
                    }
                }
                else
                {
                    if (B == null)
                    {
                        // A is greater
                        return 1;
                    }
                    else
                    {
                        return A.X.CompareTo(B.X);
                    }
                }
            }
        }

        private byte[] aIGC(int Iteration)
        {
            // all Iterations Graph Color

            switch (Iteration)
            {
                case 0: return new byte[] { 0, 0, 0 };

                case 1: return new byte[] { 255, 0, 0 };

                case 2: return new byte[] { 0, 255, 0 };

                case 3: return new byte[] { 0, 0, 255 };

                case 4: return new byte[] { 0, 255, 255 };

                case 5: return new byte[] { 255, 255, 0 };

                case 6: return new byte[] { 255, 0, 255 };

                case 7: return new byte[] { 255, 100, 100 };

                case 8: return new byte[] { 100, 255, 100 };

                case 9: return new byte[] { 100, 100, 255 };

                case 10: return new byte[] { 100, 100, 100 };

                case 11: return new byte[] { 255, 255, 100 };

                case 12: return new byte[] { 255, 100, 255 };

                case 13: return new byte[] { 100, 255, 255 };

                case 14: return new byte[] { 50, 255, 100 };

                case 15: return new byte[] { 255, 50, 100 };

                default:
                    Random rnd = new Random();
                    return new byte[]
                    {
                        (byte)((rnd.Next(0, 255 / (Iteration + 1))) * (Iteration + 1)),                    
                        (byte)((rnd.Next(0, 255 / (Iteration + 1))) * (Iteration + 1)),
                        (byte)((rnd.Next(0, 255 / (Iteration + 1))) * (Iteration + 1))
                    };
            }
        }

        #endregion



        #region -_-                 Draw New Figure                    -_-

        // Height and Width TextBoxes 
        private void FSW_TB_KeyDown(object sender, KeyEventArgs e)
        {
            FSW_TB.Text = (Convert.ToInt32(FSW_TB.Text.Trim())).ToString();

            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    if (FSW_TB.Text.Trim() != "" &&
                        FSW_TB.Text.Trim() != "0" &&
                        FSH_TB.Text.Trim() != "" &&
                        FSH_TB.Text.Trim() != "0")
                    {
                        Initialize_Drawing_New_Figure();
                    }
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void FSH_TB_KeyDown(object sender, KeyEventArgs e)
        {
            FSH_TB.Text = (Convert.ToInt32(FSH_TB.Text.Trim())).ToString();

            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    if (FSW_TB.Text.Trim() != "" &&
                        FSW_TB.Text.Trim() != "0" &&
                        FSH_TB.Text.Trim() != "" &&
                        FSH_TB.Text.Trim() != "0")
                    {
                        Initialize_Drawing_New_Figure();
                    }
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }

        private void FSW_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Keyboard.Focus(FSW_TB);
            FSW_TB.SelectAll();
        }
        private void FSH_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Keyboard.Focus(FSH_TB);
            FSH_TB.SelectAll();
        }

        private void FSW_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (FSW_TB.Text.Trim() == "")
                FSW_TB.Text = "0";
            else
                FSW_TB.Text = (Convert.ToInt32(FSW_TB.Text)).ToString();

            FSW_TB.SelectionStart = FSW_TB.Text.Length;
        }
        private void FSH_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (FSH_TB.Text.Trim() == "")
                FSH_TB.Text = "0";
            else
                FSH_TB.Text = (Convert.ToInt32(FSH_TB.Text)).ToString();

            FSH_TB.SelectionStart = FSH_TB.Text.Length;
        }



        // Add new Figure L click, this initializes creating new figure
        private void Draw_new_figure_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Draw_new_figure_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Draw_new_figure_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Draw_new_figure_L.Foreground = Button_Mouse_Leave_Color;
        }
        private void Draw_new_figure_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Initialize_Drawing_New_Figure();
        }

        private void Initialize_Drawing_New_Figure()
        {
            SCV = true;

            New_Figure_Canvas.Children.Clear();
            Last_turned_on_Pixels_for_preview = 0;

            max_x = Convert.ToInt32(FSW_TB.Text);
            max_y = Convert.ToInt32(FSH_TB.Text);

            if (number_of_drawn_figures == 0)
            {
                FSH_TB.Focusable = false;
                FSW_TB.Focusable = false;

                Initialize_temp_Matrix();

                R_of_PF_RB.IsEnabled = false;
                RD_TB.Focusable = false;
                RD_TB.IsReadOnly = true;
            }
            else
            {
                Reset_temp_Matrix();

                R_of_PF_RB.IsEnabled = true;
                RD_TB.Focusable = true;
                RD_TB.IsReadOnly = false;
            }

            Process_and_Details_Tab.SelectedIndex = 1;
            Set_New_Figure_Canvas_Size();
            //Draw_Grid();
            Reset_Text_Boxes_n_RadioButtons();

            SCV = false;
        }        


        // Add Preview Button
        private void Save_Preview_Figure_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Save_Preview_Figure_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Save_Preview_Figure_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Save_Preview_Figure_L.Foreground = Button_Mouse_Leave_Color;
        }
        private void Save_Preview_Figure_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            /*New_Figure_Canvas.Children.RemoveRange(
                        New_Figure_Canvas.Children.Count - Last_turned_on_Pixels_for_preview,
                        New_Figure_Canvas.Children.Count);*/

            Drawing_Preview_of_New_Figure = false;
            Draw_n_Review_Pixel_Brush = new SolidColorBrush(Colors.Blue);

            foreach (var item in Preview_Pixels)
            {
                if ((int)item.Key.X < max_x && (int)item.Key.X >= 0 &&
                    (int)item.Key.Y < max_y && (int)item.Key.Y >= 0)
                    temp_Matrix[(int)item.Key.X][(int)item.Key.Y] = true;
            }

            Preview_Pixels.Clear();
            Draw_Preview_Pixels();

            Add_this_Figure_L.IsEnabled = true;
            Add_this_Figure_L.Foreground = new SolidColorBrush(Colors.White);

            Last_turned_on_Pixels_for_preview = 0;
        }



        // Cancel New Figure adding process
        private void Cancel_adding_new_Figure_MouseEnter(object sender, MouseEventArgs e)
        {
            Cancel_adding_new_Figure.Foreground = Button_Mouse_Enter_Color;
        }
        private void Cancel_adding_new_Figure_MouseLeave(object sender, MouseEventArgs e)
        {
            Cancel_adding_new_Figure.Foreground = Button_Mouse_Leave_Color;
        }
        private void Cancel_adding_new_Figure_MouseDown(object sender, MouseButtonEventArgs e)
        {
            New_Figure_Canvas.Children.Clear();

            Process_and_Details_Tab.SelectedIndex = 0;
        }


        // Add the preview figure to Figures list
        private void Add_this_Figure_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Add_this_Figure_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Add_this_Figure_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Add_this_Figure_L.Foreground = Button_Mouse_Leave_Color;
        }
        private void Add_this_Figure_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Add_this_Figure_L.Content = "Save in progress ...";
            Save_Drawn_Figure.RunWorkerAsync();
        }


        // Add a new figure that is rotation of X-degree of previous shape
        private void R_of_PF_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (SCV == false)
            {
                Handle_R_of_PF_Check();
            }
        }
        private void RD_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.OemMinus:
                case Key.Subtract:
                    e.Handled = false;
                    break;

                case Key.Decimal:
                case Key.OemPeriod:
                    bool Dot_Found = false;
                    for (int i = 0; i < RD_TB.Text.Length; i++)
                    {
                        if (RD_TB.Text[i] == '.')
                        {
                            Dot_Found = true;
                            i = RD_TB.Text.Length;
                        }
                    }

                    e.Handled = Dot_Found;
                    break;

                case Key.Enter:
                    Handle_R_of_PF_request();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void RD_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (RD_TB != null &&
                PS_Grid != null &&
                R_of_PF_RB != null)
            {
                RD_TB.SelectAll();

                if(R_of_PF_RB != null)
                    if (R_of_PF_RB.IsChecked == false &&
                        SCV == false)
                    {
                        Handle_R_of_PF_Check();
                    }
            }
        }
        private void RD_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            RD_TB.Text = RD_TB.Text.Trim();

            if (RD_TB.Text == "")
                RD_TB.Text = "0";
            else if (RD_TB.Text == "0-")
                RD_TB.Text = "-";
            else if (RD_TB.Text != "-")
                RD_TB.Text = (Convert.ToDouble(RD_TB.Text)).ToString();

            RD_TB.SelectionStart = RD_TB.Text.Length;
        }

        private void Draw_PFR_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Draw_PFR_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Draw_PFR_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Draw_PFR_L.Foreground = new SolidColorBrush(Color.FromArgb(255, 154, 169, 180));
        }
        private void Draw_PFR_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Handle_R_of_PF_request();
        }

        private void Handle_R_of_PF_request()
        {
            if (string.IsNullOrEmpty(RD_TB.Text))
            {
                RD_TB.Text = "0";
                EQ_TB.Text = "Previous figure is NOT rotated";
            }
            else
            {
                EQ_TB.Text = "Previous figure is " + RD_TB.Text + " degrees rotated";
            }

            Draw_Preview();
        }
        private void Handle_R_of_PF_Check()
        {
            Ad_Random_Points_RB.IsChecked = false;
            AN_Line_RB.IsChecked = false;
            AN_Circle_RB.IsChecked = false;

            Last_turned_on_Pixels_for_preview = 0;

            EQ_TB.FontSize = 12;
            EQ_TB.Text = "Rotate previous shape " + RD_TB.Text + " degree";

            my_MessageBox my_msgbox = new my_MessageBox();
            my_msgbox.Show("\nThis option will erase the current figure and replaces it with previous figure !" +
                "\nDo you want to continue ?", 1);

            my_msgbox.ShowDialog();

            if (my_msgbox.Result() == "YES")
            {
                RD_TB.Text = "0";

                #region Clear all current pixels

                //Draw_Grid();

                Set_New_Figure_Canvas_Size();

                for (int x = 0; x < max_x; x++)
                    for (int y = 0; y < max_y; y++)
                        temp_Matrix[x][y] = false;

                #endregion

                #region Load Previous Figure
                Preview_Pixels.Clear();

                int f_size = Figures.Count - 1;
                for (int x = 0; x < max_x; x++)
                    for (int y = 0; y < max_y; y++)
                    {
                        if (Figures[f_size][x][y] == true)
                            Preview_Pixels.Add(new Point() { X = x, Y = y }, true);
                    }

                Draw_Preview_Pixels();

                #endregion

                SCV = true;
                R_of_PF_RB.IsChecked = true;
                SCV = false;
            }
            else
            {
                R_of_PF_RB.IsChecked = false;
            }

            PS_Grid.Background = new SolidColorBrush(Color.FromArgb(255, 134, 149, 160));
            RF_Grid.Background = new SolidColorBrush(Colors.Transparent);
            BS_Grid.Background = new SolidColorBrush(Colors.Transparent);

            Draw_PFR_L.Visibility = Visibility.Visible;
            Draw_Random_Points_L.Visibility = Visibility.Hidden;
            Draw_Line_or_Circle_L.Visibility = Visibility.Hidden;
        }


        // Add random points
        private void Ad_Random_Points_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null &&
                RP_Count_TB != null)
            {
                R_of_PF_RB.IsChecked = false;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;

                PS_Grid.Background = new SolidColorBrush(Colors.Transparent);
                RF_Grid.Background = new SolidColorBrush(Color.FromArgb(255, 134, 149, 160));
                BS_Grid.Background = new SolidColorBrush(Colors.Transparent);

                Draw_PFR_L.Visibility = Visibility.Hidden;
                Draw_Random_Points_L.Visibility = Visibility.Visible;
                Draw_Line_or_Circle_L.Visibility = Visibility.Hidden;


                EQ_TB.FontSize = 12;
                EQ_TB.Text = "Add " + RP_Count_TB.Text + " random points";
            }
        }

        private void RP_Count_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                            RP_Count_TB != null &&
                            R_of_PF_RB != null &&
                            AN_Line_RB != null &&
                            AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;

                RP_Count_TB.SelectAll();
            }
        }
        private void RP_Count_TB_KeyDown(object sender, KeyEventArgs e)
        {
            RP_Count_TB.Text = RP_Count_TB.Text.Trim();

            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Handle_Request_4_Random_Point_Draw();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void RP_Count_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            RP_Count_TB.Text = RP_Count_TB.Text.Trim();

            if (RP_Count_TB.Text == "")
                RP_Count_TB.Text = "0";
        }
        private void RP_Count_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            RP_Count_TB.Foreground = new SolidColorBrush(Colors.Black);

            RP_Count_TB.Text = RP_Count_TB.Text.Trim();

            if (RP_Count_TB.Text != "")
                RP_Count_TB.Text = (Convert.ToInt32(RP_Count_TB.Text)).ToString();

            RP_Count_TB.SelectionStart = RP_Count_TB.Text.Length;
        }

        private void R_F_R_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;
            }
        }
        private void R_R_R_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;


                R_AP.Text = "        A (                        ,                       )";
                R_BP.Text = "        B (                        ,                       )";

                R_BY_TB.Visibility = Visibility.Visible;
            }
        }
        private void R_C_R_RB_Checked(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;


                R_AP.Text = "Center (                       ,                       )";
                R_BP.Text = "Radius";

                R_BY_TB.Visibility = Visibility.Hidden;
            }
        }

        private void R_AX_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;

                R_AX_TB.SelectAll();
            }
        }
        private void R_AY_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;

                R_AY_TB.SelectAll();
            }
        }
        private void R_BX_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;

                R_BX_TB.SelectAll();
            }
        }
        private void R_BY_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            if (EQ_TB != null &&
                RP_Count_TB != null &&
                R_of_PF_RB != null &&
                AN_Line_RB != null &&
                AN_Circle_RB != null)
            {
                Ad_Random_Points_RB.IsChecked = true;
                AN_Line_RB.IsChecked = false;
                AN_Circle_RB.IsChecked = false;
                R_of_PF_RB.IsChecked = false;

                R_BY_TB.SelectAll();
            }
        }

        private void R_AX_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            R_AX_TB.Text = R_AX_TB.Text.Trim();

            if (string.IsNullOrEmpty(R_AX_TB.Text))
                R_AX_TB.Text = "0";

            else if (Convert.ToInt32(R_AX_TB.Text) > max_x)
                R_AX_TB.Text = max_x.ToString();
        }
        private void R_AY_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            R_AY_TB.Text = R_AY_TB.Text.Trim();

            if (string.IsNullOrEmpty(R_AY_TB.Text))
                R_AY_TB.Text = "0";

            else if (Convert.ToInt32(R_AY_TB.Text) > max_y)
                R_AY_TB.Text = max_y.ToString();
        }
        private void R_BX_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            R_BX_TB.Text = R_BX_TB.Text.Trim();

            if (string.IsNullOrEmpty(R_BX_TB.Text))
                R_BX_TB.Text = "0";

            else if (R_C_R_RB.IsChecked == false && Convert.ToInt32(R_BX_TB.Text) > max_x)
                R_BX_TB.Text = max_x.ToString();
        }
        private void R_BY_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            R_BY_TB.Text = R_BY_TB.Text.Trim();

            if (string.IsNullOrEmpty(R_BY_TB.Text))
                R_BY_TB.Text = "0";

            else if (R_C_R_RB.IsChecked == false && Convert.ToInt32(R_BY_TB.Text) > max_y)
                R_BY_TB.Text = max_y.ToString();
        }

        private void R_AX_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Handle_Request_4_Random_Point_Draw();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void R_AY_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Handle_Request_4_Random_Point_Draw();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void R_BX_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Handle_Request_4_Random_Point_Draw();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void R_BY_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.Tab:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Handle_Request_4_Random_Point_Draw();
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }

        private void R_AX_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            R_AX_TB.Foreground = new SolidColorBrush(Colors.Black);

            R_AX_TB.Text = R_AX_TB.Text.Trim();

            if (R_AX_TB.Text != "")
                R_AX_TB.Text = (Convert.ToInt32(R_AX_TB.Text)).ToString();

            R_AX_TB.SelectionStart = R_AX_TB.Text.Length;
        }
        private void R_AY_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            R_AY_TB.Foreground = new SolidColorBrush(Colors.Black);

            R_AY_TB.Text = R_AY_TB.Text.Trim();

            if (R_AY_TB.Text != "")
                R_AY_TB.Text = (Convert.ToInt32(R_AY_TB.Text)).ToString();

            R_AY_TB.SelectionStart = R_AY_TB.Text.Length;
        }
        private void R_BX_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            R_BX_TB.Foreground = new SolidColorBrush(Colors.Black);

            R_BX_TB.Text = R_BX_TB.Text.Trim();

            if (R_BX_TB.Text != "")
                R_BX_TB.Text = (Convert.ToInt32(R_BX_TB.Text)).ToString();

            R_BX_TB.SelectionStart = R_BX_TB.Text.Length;
        }
        private void R_BY_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            R_BY_TB.Foreground = new SolidColorBrush(Colors.Black);

            R_BY_TB.Text = R_BY_TB.Text.Trim();

            if (R_BY_TB.Text != "")
                R_BY_TB.Text = (Convert.ToInt32(R_BY_TB.Text)).ToString();

            R_BY_TB.SelectionStart = R_BY_TB.Text.Length;
        }

        private void Draw_Random_Points_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Draw_Random_Points_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Draw_Random_Points_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Draw_Random_Points_L.Foreground = new SolidColorBrush(Color.FromArgb(255, 154, 169, 180));
        }
        private void Draw_Random_Points_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Handle_Request_4_Random_Point_Draw();
        }

        private void Handle_Request_4_Random_Point_Draw()
        {
            Ad_Random_Points_RB.IsChecked = true;
            AN_Line_RB.IsChecked = false;
            AN_Circle_RB.IsChecked = false;
            R_of_PF_RB.IsChecked = false;

            if (string.IsNullOrEmpty(RP_Count_TB.Text))
            {
                RP_Count_TB.Text = "0";
                EQ_TB.Text = "No random point is added";
            }
            else
            {
                EQ_TB.Text = "Add " + RP_Count_TB.Text + " random points";
            }

            Draw_Preview();
        }



        // Progress step slider
        private void Progress_Step_Size_Slider_GotFocus(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            if (AN_Circle_RB.IsChecked == false)
                AN_Line_RB.IsChecked = true;
        }
        private void Progress_Step_Size_Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (SCV == false && Instant_Progress_Step_Apply != null)
            {
                Drawing_Progress_Step_Size = Math.Round(Progress_Step_Size_Slider.Value, 2);
                Progress_Step_Size_L.Text = "Progress Step Size : " + Drawing_Progress_Step_Size.ToString();

                if (Instant_Progress_Step_Apply.IsChecked == true)
                    Draw_Preview();
            }
        }



        // Add Lines and Circles
        private void AN_Line_RB_Checked(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            EQ_TB.FontSize = 14;
            EQ_TB.Text = "y = mx + c";

            AN_AP.Text = "        A (                        ,                       )";
            AN_BP.Text = "        B (                        ,                       )";

            AN_BY_TB.Visibility = Visibility.Visible;
        }
        private void AN_Circle_RB_Checked(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            EQ_TB.FontSize = 14;
            EQ_TB.Text = "x ^ 2  +  y ^ 2  =  r ^ 2";

            AN_AP.Text = "Center (                       ,                       )";
            AN_BP.Text = "Radius";

            AN_BY_TB.Visibility = Visibility.Hidden;
        }

        private void Handle_Common_Changes_4_Lines_n_Circles_Draw()
        {
            PS_Grid.Background = new SolidColorBrush(Colors.Transparent);
            RF_Grid.Background = new SolidColorBrush(Colors.Transparent);
            BS_Grid.Background = new SolidColorBrush(Color.FromArgb(255, 134, 149, 160));

            Draw_PFR_L.Visibility = Visibility.Hidden;
            Draw_Random_Points_L.Visibility = Visibility.Hidden;
            Draw_Line_or_Circle_L.Visibility = Visibility.Visible;

            Ad_Random_Points_RB.IsChecked = false;
            R_of_PF_RB.IsChecked = false;
        }


        // Draw the specified (by relative textboxes) line or circle lable
        private void Draw_Line_or_Circle_L_MouseEnter(object sender, MouseEventArgs e)
        {
            Draw_Line_or_Circle_L.Foreground = Button_Mouse_Enter_Color;
        }
        private void Draw_Line_or_Circle_L_MouseLeave(object sender, MouseEventArgs e)
        {
            Draw_Line_or_Circle_L.Foreground = new SolidColorBrush(Color.FromArgb(255, 154, 169, 180));
        }
        private void Draw_Line_or_Circle_L_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Draw_Preview();
        }


        private void AN_AX_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Draw_Preview();
                    break;

                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void AN_AY_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Draw_Preview();
                    break;

                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void AN_BX_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Draw_Preview();
                    break;

                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }
        private void AN_BY_TB_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                    e.Handled = false;
                    break;

                case Key.Enter:
                    Draw_Preview();
                    break;

                case Key.Tab:
                    e.Handled = false;
                    break;

                default:
                    e.Handled = true;
                    break;
            }
        }

        private void AN_AX_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            if (AN_Circle_RB.IsChecked == false)
                AN_Line_RB.IsChecked = true;

            AN_AX_TB.SelectAll();
        }
        private void AN_AY_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            if (AN_Circle_RB.IsChecked == false)
                AN_Line_RB.IsChecked = true;

            AN_AY_TB.SelectAll();
        }
        private void AN_BX_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            if (AN_Circle_RB.IsChecked == false)
                AN_Line_RB.IsChecked = true;

            AN_BX_TB.SelectAll();
        }
        private void AN_BY_TB_GotFocus(object sender, RoutedEventArgs e)
        {
            Handle_Common_Changes_4_Lines_n_Circles_Draw();

            if (AN_Circle_RB.IsChecked == false)
                AN_Line_RB.IsChecked = true;

            AN_BY_TB.SelectAll();
        }

        private void AN_AX_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            AN_AX_TB.Text = AN_AX_TB.Text.Trim();

            if (string.IsNullOrEmpty(AN_AX_TB.Text))
                AN_AX_TB.Text = "0";

            else if (Convert.ToInt32(AN_AX_TB.Text) > max_x)
                AN_AX_TB.Text = max_x.ToString();
        }
        private void AN_AY_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            AN_AY_TB.Text = AN_AY_TB.Text.Trim();

            if (string.IsNullOrEmpty(AN_AY_TB.Text))
                AN_AY_TB.Text = "0";

            else if (Convert.ToInt32(AN_AY_TB.Text) > max_y)
                AN_AY_TB.Text = max_y.ToString();
        }
        private void AN_BX_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            AN_BX_TB.Text = AN_BX_TB.Text.Trim();

            if (string.IsNullOrEmpty(AN_BX_TB.Text))
                AN_BX_TB.Text = "0";

            else if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BX_TB.Text) > max_x)
                AN_BX_TB.Text = max_x.ToString();
        }
        private void AN_BY_TB_LostFocus(object sender, RoutedEventArgs e)
        {
            AN_BY_TB.Text = AN_BY_TB.Text.Trim();

            if (string.IsNullOrEmpty(AN_BY_TB.Text))
                AN_BY_TB.Text = "0";

            else if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BY_TB.Text) > max_y)
                AN_BY_TB.Text = max_y.ToString();
        }

        private void AN_AX_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            AN_AX_TB.Foreground = new SolidColorBrush(Colors.Black);

            AN_AX_TB.Text = AN_AX_TB.Text.Trim();

            if (!string.IsNullOrEmpty(AN_AX_TB.Text))
            {
                AN_AX_TB.Text = (Convert.ToInt32(AN_AX_TB.Text)).ToString();

                if (Convert.ToInt32(AN_AX_TB.Text) > max_x)
                    AN_AX_TB.Text = max_x.ToString();
            }

            AN_AX_TB.SelectionStart = AN_AX_TB.Text.Length;
        }
        private void AN_AY_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            AN_AY_TB.Foreground = new SolidColorBrush(Colors.Black);

            AN_AY_TB.Text = AN_AY_TB.Text.Trim();

            if (!string.IsNullOrEmpty(AN_AY_TB.Text))
            {
                AN_AY_TB.Text = (Convert.ToInt32(AN_AY_TB.Text)).ToString();

                if (Convert.ToInt32(AN_AY_TB.Text) > max_y)
                    AN_AY_TB.Text = max_y.ToString();
            }

            AN_AY_TB.SelectionStart = AN_AY_TB.Text.Length;
        }
        private void AN_BX_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            AN_BX_TB.Foreground = new SolidColorBrush(Colors.Black);

            AN_BX_TB.Text = AN_BX_TB.Text.Trim();

            if (!string.IsNullOrEmpty(AN_BX_TB.Text))
            {
                AN_BX_TB.Text = (Convert.ToInt32(AN_BX_TB.Text)).ToString();

                if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BX_TB.Text) > max_x)
                    AN_BX_TB.Text = max_x.ToString();
            }

            AN_BX_TB.SelectionStart = AN_BX_TB.Text.Length;
        }
        private void AN_BY_TB_TextChanged(object sender, TextChangedEventArgs e)
        {
            AN_BY_TB.Foreground = new SolidColorBrush(Colors.Black);

            AN_BY_TB.Text = AN_BY_TB.Text.Trim();

            if (!string.IsNullOrEmpty(AN_BY_TB.Text))
            {
                AN_BY_TB.Text = (Convert.ToInt32(AN_BY_TB.Text)).ToString();

                if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BY_TB.Text) > max_y)
                    AN_BY_TB.Text = max_y.ToString();
            }

            AN_BY_TB.SelectionStart = AN_BY_TB.Text.Length;
        }

        private void Check_Line_or_Circle_Drawing_TBs()
        {
            if (string.IsNullOrEmpty(AN_AX_TB.Text))
                AN_AX_TB.Text = "0";

            if (string.IsNullOrEmpty(AN_AY_TB.Text))
                AN_AY_TB.Text = "0";

            if (string.IsNullOrEmpty(AN_BX_TB.Text))
                AN_BX_TB.Text = "0";

            if (string.IsNullOrEmpty(AN_BY_TB.Text))
                AN_BY_TB.Text = "0";


            if (Convert.ToInt32(AN_AX_TB.Text) > max_x)
                AN_AX_TB.Text = max_x.ToString();

            if (Convert.ToInt32(AN_AY_TB.Text) > max_y)
                AN_AY_TB.Text = max_y.ToString();

            if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BX_TB.Text) > max_x)
                AN_BX_TB.Text = max_x.ToString();

            if (AN_Line_RB.IsChecked == true && Convert.ToInt32(AN_BY_TB.Text) > max_y)
                AN_BY_TB.Text = max_y.ToString();

            Drawing_Progress_Step_Size = Math.Round(Progress_Step_Size_Slider.Value, 2);
            Progress_Step_Size_L.Text = "Progress Step Size : " + Drawing_Progress_Step_Size.ToString();
        }
        private void Draw_Preview()
        {
            if (SCV == false)
            {
                Check_Line_or_Circle_Drawing_TBs();

                Draw_n_Review_Pixel_Brush = new SolidColorBrush(Color.FromArgb(255, 250, 225, 0));
                Drawing_Preview_of_New_Figure = true;

                /*New_Figure_Canvas.Children.RemoveRange(
                    New_Figure_Canvas.Children.Count - Last_turned_on_Pixels_for_preview,
                    New_Figure_Canvas.Children.Count);*/

                Last_turned_on_Pixels_for_preview = 0;

                if (R_of_PF_RB != null &&
                    AN_Line_RB != null &&
                    AN_Circle_RB != null &&
                    Ad_Random_Points_RB != null)
                {
                    if (R_of_PF_RB.IsChecked == true)
                        Rotate_Previous_Shape();

                    else if (Ad_Random_Points_RB.IsChecked == true)
                        Add_Random_Points();

                    else if (AN_Line_RB.IsChecked == true)
                        Add_Line();

                    else if (AN_Circle_RB.IsChecked == true)
                        Add_Circ();
                }
            }
        }

        private void Add_Line()
        {
            if (Check_TB_4_L_n_C() != false)
            {
                Preview_Pixels.Clear();

                double
                    x0 = Convert.ToDouble(AN_AX_TB.Text),
                    y0 = Convert.ToDouble(AN_AY_TB.Text),
                    x1 = Convert.ToDouble(AN_BX_TB.Text),
                    y1 = Convert.ToDouble(AN_BY_TB.Text),
                    c = 0.0,
                    m = 0.0;


                if (x0 != x1)
                    EQ_TB.Text = "y = " + m.ToString() + "x + ( " + c.ToString() + " )";
                else
                    if (y0 != y1)
                        EQ_TB.Text = "y = " + x0.ToString();
                    else
                        EQ_TB.Text = "Pixel : " + x0.ToString() + " , " + y0.ToString();



                if (x0 < x1)
                {
                    m = Convert.ToDouble(Math.Round(Convert.ToDecimal((y1 - y0) / (x1 - x0)), 2));
                    c = Convert.ToDouble(Math.Round(Convert.ToDecimal(((x1 * y0) - (x0 * y1)) / (x1 - x0)), 2));

                    for (double x = x0; x < x1; x++)
                    {
                        Point newPoint = new Point { X = Math.Round(x), Y = Math.Round((m * x) + c) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                        x--;
                        x = x + Drawing_Progress_Step_Size;
                    }
                }

                else if (x0 > x1)
                {
                    m = Convert.ToDouble(Math.Round(Convert.ToDecimal((y1 - y0) / (x1 - x0)), 2));
                    c = Convert.ToDouble(Math.Round(Convert.ToDecimal(((x1 * y0) - (x0 * y1)) / (x1 - x0)), 2));

                    for (double x = x0; x > x1; x--)
                    {
                        Point newPoint = new Point { X = Math.Round(x), Y = Math.Round((m * x) + c) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                        x--;
                        x = x + Drawing_Progress_Step_Size;
                    }
                }

                else if (x0 == x1)
                {
                    if (y0 < y1)
                    {
                        for (double y = y0; y < y1; y++)
                        {
                            Point newPoint = new Point { X = Math.Round(x0), Y = Math.Round(y) };
                            if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                            y--;
                            y = y + Drawing_Progress_Step_Size;
                        }
                    }
                    else
                    {
                        if (y0 > y1)
                        {
                            for (double y = y0; y > y1; y--)
                            {
                                Point newPoint = new Point { X = Math.Round(x0), Y = Math.Round(y) };
                                if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                                y--;
                                y = y + Drawing_Progress_Step_Size;
                            }
                        }
                        else
                        {
                            //Turn_On_Pixel(x0, y0);
                        }
                    }
                }

                Draw_Preview_Pixels();
            }
        }
        private void Add_Circ()
        {
            if (Check_TB_4_L_n_C() != false)
            {
                Preview_Pixels.Clear();

                double
                   a = Convert.ToDouble(AN_AX_TB.Text),
                   b = Convert.ToDouble(AN_AY_TB.Text),
                   r = Convert.ToDouble(AN_BX_TB.Text);

                int R = Convert.ToInt16(r);

                EQ_TB.Text = "(x - " + AN_AX_TB.Text + " )^2  +  ( y - " + AN_AY_TB.Text + " )^2  =  " + AN_BX_TB.Text + " ^2";

                bool Collision = false;

                for (double i = 0; i <= R; i++)
                {
                    double
                        Y_U = b - Math.Pow((Math.Pow(r, 2) - Math.Pow(i, 2)), 0.5),
                        Y_D = b + Math.Pow((Math.Pow(r, 2) - Math.Pow(i, 2)), 0.5);

                    if (Collision == false)
                    {
                        if (Y_D == Y_U) Collision = true;
                        Point newPoint = new Point { X = Math.Round(a + i), Y = Math.Round(Y_U) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);
                        
                        newPoint = new Point { X = Math.Round(a + i), Y = Math.Round(Y_D) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                        newPoint = new Point { X = Math.Round(a - i), Y = Math.Round(Y_U) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                        newPoint = new Point { X = Math.Round(a - i), Y = Math.Round(Y_D) };
                        if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);
                    }
                    else
                        i = R + 1;

                    i--;
                    i = i + Drawing_Progress_Step_Size;
                }

                Draw_Preview_Pixels();
            }
        }
        private void Add_Random_Points()
        {
            if (R_F_R_RB != null &&
                R_R_R_RB != null &&
                R_C_R_RB != null &&
                RP_Count_TB != null)
            {
                if (RP_Count_TB.Text.Trim() != "0")
                {
                    if (Check_TB_4_RP() == true)
                    {
                        Preview_Pixels.Clear();

                        A_R_N_Report_L.Visibility = Visibility.Visible;

                        Add_Random_Pixels_BW.RunWorkerAsync(Convert.ToInt32(RP_Count_TB.Text));
                    }
                }
                else
                {
                    RP_Count_TB.Foreground = new SolidColorBrush(Colors.Red);
                }
            }
        }
        private void Rotate_Previous_Shape()
        {
            int ii = Preview_Pixels.Count;

            double R = 360 - Convert.ToDouble(RD_TB.Text);

            double
                x_min = 999999,
                x_max = -999999,
                x_trans = 0,
                y_min = 999999,
                y_max = -999999,
                y_trans = 0;

            // Apply Rotation

            List<Point> tmpKeys = new List<Point>();            
            foreach (var item in Preview_Pixels)
                tmpKeys.Add(new Point(item.Key.X, item.Key.Y));
            Preview_Pixels.Clear();
            foreach (var point in tmpKeys)
            {
                Point newPoint = new Point()
                {
                    X =
                    Convert.ToDouble(Math.Round(
                    point.X * Math.Cos((Math.PI * R) / 180) -
                    point.Y * Math.Sin((Math.PI * R) / 180))),

                    Y = Convert.ToDouble(Math.Round(
                    point.X * Math.Sin((Math.PI * R) / 180) +
                    point.Y * Math.Cos((Math.PI * R) / 180)))
                };

                if (!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);

                if (newPoint.X < x_min)
                    x_min = newPoint.X;
                else if (newPoint.X > x_max)
                    x_max = newPoint.X;

                if (newPoint.Y < y_min)
                    y_min = newPoint.Y;
                else if (newPoint.Y > y_max)
                    y_max = newPoint.Y;
            }


            if (x_min < 0)
                x_trans = ((-1) * x_min) + 1;
            else
                if (x_max > max_x)
                    x_trans = (-1) * (x_max - max_x + 1);
                else
                    x_trans = 0;

            if (y_min < 0)
                y_trans = ((-1) * y_min) + 1;
            else
                if (y_max > max_y)
                    y_trans = (-1) * (y_max - max_y + 1);
                else
                    y_trans = 0;


            // Re-Coordinate
            tmpKeys = new List<Point>();
            foreach (var item in Preview_Pixels)
                tmpKeys.Add(new Point(item.Key.X, item.Key.Y));
            Preview_Pixels.Clear();
            foreach (var item in tmpKeys)
            {
                Point newPoint = new Point()
                {
                    X = item.X + x_trans,
                    Y = item.Y + y_trans
                };
                if(!Preview_Pixels.ContainsKey(newPoint)) Preview_Pixels.Add(newPoint, true);
            }

            Draw_Preview_Pixels();
        }

        private void Draw_Preview_Pixels()
        {
            Color onColor = Colors.Red;
            Color offColor = Colors.Transparent;
            Color previewColor = Colors.Yellow;

            List<Color> colors = new List<Color>();
            colors.Add(onColor);
            colors.Add(offColor);
            colors.Add(previewColor);
            BitmapPalette palette = new BitmapPalette(colors);
            PixelFormat pixelFormat = PixelFormats.Bgra32;

            int stride = max_x * 4;

            byte[] pixels = new byte[max_y * stride];
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                {
                    if (Preview_Pixels.ContainsKey(new Point(x, y)))
                    {
                        pixels[(x * 4) + (y * stride) + 0] = previewColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = previewColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = previewColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = previewColor.A;
                    }
                    else if (temp_Matrix[x][y] == true)
                    {
                        pixels[(x * 4) + (y * stride) + 0] = onColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = onColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = onColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = onColor.A;
                    }
                    else
                    {
                        pixels[(x * 4) + (y * stride) + 0] = offColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = offColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = offColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = offColor.A;
                    }
                }


            var bitmap = BitmapSource.Create(max_x, max_y, 96, 96, pixelFormat, palette, pixels, stride);
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = bitmap;
            New_Figure_Canvas.Background = ib;

            /*foreach (Point P in Preview_Pixels)
            {
                Rectangle On_Pixel = new Rectangle();
                On_Pixel.Width = P_W;
                On_Pixel.Height = P_H;
                On_Pixel.Fill = Draw_n_Review_Pixel_Brush;
                Canvas.SetLeft(On_Pixel, (P.X * P_W) + 4);
                Canvas.SetTop(On_Pixel, (P.Y * P_H) + 4);
                New_Figure_Canvas.Children.Add(On_Pixel);

                Last_turned_on_Pixels_for_preview++;
            }*/
        }
        private void Turn_On_Pixel(double x, double y)
        {
            if (x < max_x && y < max_y && x >= 0 && y >= 0)
            {
                int new_x = Convert.ToInt16(Math.Round(x)),
                    new_y = Convert.ToInt16(Math.Round(y));

                Rectangle On_Pixel = new Rectangle();
                On_Pixel.Width = P_W;
                On_Pixel.Height = P_H;
                On_Pixel.Fill = Draw_n_Review_Pixel_Brush;
                Canvas.SetLeft(On_Pixel, new_x * P_W);
                Canvas.SetTop(On_Pixel, new_y * P_H);
                New_Figure_Canvas.Children.Add(On_Pixel);

                if (!Drawing_Preview_of_New_Figure)
                    temp_Matrix[new_x][new_y] = true;

                Last_turned_on_Pixels_for_preview++;
            }
        }


        private void Draw_Grid()
        {
            New_Figure_Canvas.Children.Clear();

            matrix_Size = max_x * max_y;
            P_H = Convert.ToDouble(New_Figure_Canvas.Height - 8.0) / max_y;
            P_W = Convert.ToDouble(New_Figure_Canvas.Width - 8.0) / max_x;

            double
                max_Width = New_Figure_Canvas.Width - 4.0,
                max_Height = New_Figure_Canvas.Height - 4.0;

            if (max_x <= 200 && max_y <= 200)
            {
                Rectangle Grid_Outline = new Rectangle();
                Grid_Outline.Width = New_Figure_Canvas.Width;
                Grid_Outline.Height = New_Figure_Canvas.Height;
                Grid_Outline.Fill = new SolidColorBrush(Colors.White);
                Grid_Outline.Stroke = new SolidColorBrush(Colors.Black);
                Grid_Outline.StrokeThickness = 4;
                New_Figure_Canvas.Children.Add(Grid_Outline);
                Canvas.SetTop(Grid_Outline, 0);
                Canvas.SetLeft(Grid_Outline, 0);

                SolidColorBrush Grid_Lines_B = new SolidColorBrush(Colors.LightGray);

                for (int i = 0; i < max_x; i++)
                {
                    Line V_Line = new Line();
                    V_Line.Stroke = Grid_Lines_B;
                    V_Line.StrokeThickness = 1;
                    V_Line.X1 = (i * P_W) + 4;
                    V_Line.Y1 = 4;
                    V_Line.X2 = (i * P_W) + 4;
                    V_Line.Y2 = max_Height;

                    New_Figure_Canvas.Children.Add(V_Line);
                }

                for (int i = 0; i < max_y; i++)
                {
                    Line H_Line = new Line();
                    H_Line.Stroke = Grid_Lines_B;
                    H_Line.StrokeThickness = 1;
                    H_Line.X1 = 4;
                    H_Line.Y1 = (i * P_H) + 4;
                    H_Line.X2 = max_Width;
                    H_Line.Y2 = (i * P_H) + 4;

                    New_Figure_Canvas.Children.Add(H_Line);
                }

                Rectangle Grid_Outline_2 = new Rectangle();
                Grid_Outline_2.Width = New_Figure_Canvas.Width;
                Grid_Outline_2.Height = New_Figure_Canvas.Height;
                Grid_Outline_2.Fill = new SolidColorBrush(Colors.Transparent);
                Grid_Outline_2.Stroke = new SolidColorBrush(Colors.Black);
                Grid_Outline_2.StrokeThickness = 2;
                New_Figure_Canvas.Children.Add(Grid_Outline_2);
                Canvas.SetTop(Grid_Outline_2, 0);
                Canvas.SetLeft(Grid_Outline_2, 0);
            }
            else
            {
                Rectangle Grid_Outline = new Rectangle();
                Grid_Outline.Width = New_Figure_Canvas.Width;
                Grid_Outline.Height = New_Figure_Canvas.Height;
                Grid_Outline.Fill = new SolidColorBrush(Colors.LightGray);
                Grid_Outline.Stroke = new SolidColorBrush(Colors.Black);
                Grid_Outline.StrokeThickness = 2;
                New_Figure_Canvas.Children.Add(Grid_Outline);
                Canvas.SetTop(Grid_Outline, 0);
                Canvas.SetLeft(Grid_Outline, 0);
            }
        }
        private void Set_New_Figure_Canvas_Size()
        {
            double Ratio = (double)max_x / (double)max_y;

            if (Process_and_Details_Tab.ActualWidth - 350 > Process_and_Details_Tab.ActualHeight - 150)
            {
                // Set ratio based on Width
                New_Figure_Canvas.Height = Process_and_Details_Tab.ActualHeight - 150;
                New_Figure_Canvas.Width = Ratio * (Process_and_Details_Tab.ActualHeight - 150);
            }
            else
            {
                // Set ratio based on Height
                New_Figure_Canvas.Width = Process_and_Details_Tab.ActualWidth - 350;
                New_Figure_Canvas.Height = (Process_and_Details_Tab.ActualWidth - 350) / Ratio;
            }
        }
        private void Reset_Text_Boxes_n_RadioButtons()
        {
            SCV = true;

            Figure_Name_TB.Text = "Figure " + number_of_drawn_figures.ToString();

            RD_TB.Text = "0";

            RP_Count_TB.Text = "0";
            R_AX_TB.Text = "0";
            R_AY_TB.Text = "0";
            R_BX_TB.Text = "0";
            R_BY_TB.Text = "0";

            AN_AX_TB.Text = "0";
            AN_AY_TB.Text = "0";
            AN_BX_TB.Text = "0";
            AN_BY_TB.Text = "0";
            EQ_TB.Text = "";

            R_of_PF_RB.IsChecked = false;
            Ad_Random_Points_RB.IsChecked = true;
            AN_Line_RB.IsChecked = false;
            AN_Circle_RB.IsChecked = false;

            PS_Grid.Background = new SolidColorBrush(Colors.Transparent);
            RF_Grid.Background = new SolidColorBrush(Color.FromArgb(255, 134, 149, 160));
            BS_Grid.Background = new SolidColorBrush(Colors.Transparent);

            RP_Count_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_AX_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_AY_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_BX_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_BY_TB.Foreground = new SolidColorBrush(Colors.Black);

            Add_this_Figure_L.IsEnabled = false;
            Draw_new_figure_L.IsEnabled = true;
            Undo_Figure_Design.IsEnabled = false;

            Add_this_Figure_L.Foreground = new SolidColorBrush(Colors.Gray);
            Draw_new_figure_L.Foreground = new SolidColorBrush(Colors.White);
            Undo_Figure_Design.Foreground = new SolidColorBrush(Colors.Gray);

            Drawing_Progress_Step_Size = 1;
            Progress_Step_Size_L.Text = "Progress Step Size : 1";
            Progress_Step_Size_Slider.Value = 1;

            Draw_PFR_L.Visibility = Visibility.Hidden;
            Draw_Random_Points_L.Visibility = Visibility.Visible;
            Draw_Line_or_Circle_L.Visibility = Visibility.Hidden;

            EQ_TB.Text = "";

            SCV = false;
        }


        // Check TextBoxes for Random Pixels
        private bool Check_TB_4_RP()
        {
            bool rv = true;

            R_AX_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_AY_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_BX_TB.Foreground = new SolidColorBrush(Colors.Black);
            R_BY_TB.Foreground = new SolidColorBrush(Colors.Black);

            if (R_F_R_RB.IsChecked == false)
            {
                if ((R_C_R_RB.IsChecked == false &&
                    Convert.ToInt32(R_AX_TB.Text) >= Convert.ToInt32(R_BX_TB.Text)) ||
                    Convert.ToInt32(R_AX_TB.Text) >= max_x)
                {
                    rv = false;
                    R_AX_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }

                if ((R_C_R_RB.IsChecked == false &&
                    Convert.ToInt32(R_AY_TB.Text) >= Convert.ToInt32(R_BY_TB.Text)) ||
                    Convert.ToInt32(R_AY_TB.Text) >= max_y)
                {
                    rv = false;
                    R_AY_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }

                if (R_C_R_RB.IsChecked == false && Convert.ToInt32(R_BX_TB.Text) >= max_x)
                {
                    rv = false;
                    R_BX_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }

                if (R_C_R_RB.IsChecked == false && Convert.ToInt32(R_BY_TB.Text) >= max_y)
                {
                    rv = false;
                    R_BY_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }
            }

            return rv;
        }

        // Check TextBoxes for Line and Circle Draw
        private bool Check_TB_4_L_n_C()
        {
            bool rv = true;

            if (Convert.ToInt32(AN_AX_TB.Text) >= max_x)
            {
                rv = false;
                AN_AX_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
            }

            if (Convert.ToInt32(AN_AY_TB.Text) >= max_y)
            {
                rv = false;
                AN_AY_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
            }

            if (AN_Circle_RB.IsChecked == false && Convert.ToInt32(AN_BX_TB.Text) >= max_x)
            {
                rv = false;
                AN_BX_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
            }

            if (AN_Circle_RB.IsChecked == false && Convert.ToInt32(AN_BY_TB.Text) >= max_y)
            {
                rv = false;
                AN_BY_TB.Foreground = new SolidColorBrush(Colors.OrangeRed);
            }

            return rv;
        }


        // Add Random Figures Background Worker
        private void Add_Random_Pixels_BW_DoWork(object sender, DoWorkEventArgs e)
        {
            int
                point_Count = (int)e.Argument,
                _i = (int)e.Argument;

            double
                _Steps = ((int)e.Argument) * 2.0;

            Random rnd_Number = new Random();

            int Condition = 0;

            Dispatcher.Invoke((Action)(() =>
            {
                if (R_F_R_RB.IsChecked == true)
                {
                    Condition = 1;
                }
                else if (R_R_R_RB.IsChecked == true)
                {
                    Condition = 2;
                }
                else
                {
                    Condition = 3;
                }
            }));


            switch (Condition)
            {
                case 1:
                    for (int i = 1; i <= point_Count; i++)
                    {
                        Point newPoint = new Point
                            {
                                X = rnd_Number.Next(0, max_x),
                                Y = rnd_Number.Next(0, max_y)
                            };

                        if(!Preview_Pixels.ContainsKey(newPoint))
                            Preview_Pixels.Add(newPoint, true);

                        Add_Random_Pixels_BW.ReportProgress((int)(Math.Round((i * 100.0) / _Steps, 2) * 100));
                    }
                    break;

                case 2:
                    int
                        minX = 0,
                        maxX = 0,
                        minY = 0,
                        maxY = 0;

                    Dispatcher.Invoke((Action)(() =>
                    {
                        minX = Convert.ToInt32(R_AX_TB.Text);
                        maxX = Convert.ToInt32(R_BX_TB.Text);
                        minY = Convert.ToInt32(R_AY_TB.Text);
                        maxY = Convert.ToInt32(R_BY_TB.Text);
                    }));

                    for (int i = 1; i <= point_Count; i++)
                    {
                        Point newPoint =new Point
                            {
                                X = rnd_Number.Next(minX, maxX),
                                Y = rnd_Number.Next(minY, maxY)
                            };

                        if (!Preview_Pixels.ContainsKey(newPoint))
                            Preview_Pixels.Add(newPoint, true);

                        Add_Random_Pixels_BW.ReportProgress((int)(Math.Round((i * 100.0) / _Steps, 2) * 100));
                    }
                    break;

                case 3:
                    bool within_range = false;

                    int
                        t_X = 0,
                        t_Y = 0,
                        c_X = 0,
                        c_Y = 0,
                        r = 0;

                    Dispatcher.Invoke((Action)(() =>
                        {
                            c_X = Convert.ToInt32(R_AX_TB.Text);
                            c_Y = Convert.ToInt32(R_AY_TB.Text);
                            r = Convert.ToInt32(R_BX_TB.Text);

                            R_C_R_RB.IsChecked = true;
                        }));

                    if (r == 0)
                    {
                        Dispatcher.Invoke((Action)(() =>
                        {
                            EQ_TB.Text = "No random point is added";
                        }));
                    }
                    else
                    {
                        for (int i = 1; i <= point_Count; i++)
                        {
                            within_range = false;

                            while (!within_range)
                            {
                                t_X = rnd_Number.Next(0, max_x);
                                t_Y = rnd_Number.Next(0, max_y);

                                if (Math.Sqrt(Math.Pow(t_X - c_X, 2) + Math.Pow(t_Y - c_Y, 2)) < r)
                                    within_range = true;
                            }

                            Point newPoint = new Point
                                {
                                    X = t_X,
                                    Y = t_Y
                                };

                            if (!Preview_Pixels.ContainsKey(newPoint))
                                Preview_Pixels.Add(newPoint, true);

                            Add_Random_Pixels_BW.ReportProgress((int)(Math.Round((i * 100.0) / _Steps, 2) * 100));
                        }
                    }
                    break;
            }

            #region Draw Preview
            Dispatcher.Invoke((Action)(() =>
                {
                    Draw_Preview_Pixels();
                }));
            /*
            foreach (Point P in Preview_Pixels)
            {
                _i++;
                Add_Random_Pixels_BW.ReportProgress((int)(Math.Round((_i * 100.0) / _Steps, 2) * 100));

                Dispatcher.Invoke((Action)(() =>
                {
                    Rectangle On_Pixel = new Rectangle();
                    On_Pixel.Width = P_W;
                    On_Pixel.Height = P_H;
                    On_Pixel.Fill = Draw_n_Review_Pixel_Brush;
                    Canvas.SetLeft(On_Pixel, (P.X * P_W) + 4);
                    Canvas.SetTop(On_Pixel, (P.Y * P_H) + 4);

                    New_Figure_Canvas.Children.Add(On_Pixel);
                }));
            }*/

            //Last_turned_on_Pixels_for_preview = _i - point_Count;
            #endregion
        }
        private void Add_Random_Pixels_BW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            A_R_N_Report_L.Visibility = Visibility.Hidden;
        }
        private void Add_Random_Pixels_BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            A_R_N_Report_L.Content = (((int)e.ProgressPercentage) / 100.0).ToString() + " %";

            A_R_N_Report_L.UpdateLayout();
        }


        // Save Drawn Figure BackGround Worker
        private void Save_Drawn_Figure_DoWork(object sender, DoWorkEventArgs e)
        {
            Copy_Temp_Matrix_2_Figures();
        }
        private void Save_Drawn_Figure_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Figures_Name.Add(Figure_Name_TB.Text.Trim());

            Figures_DG.Items.Clear();
            Figures_DG.Columns.Clear();

            for (int i = 0; i < Figures.Count; i++)
            {
                DataContext = new List<Figurez>
            {
                new Figurez
                {
                    Figure_ID = "Fig " + i.ToString(),
                    Figure_Name = Figures_Name[i]
                }
            };
                Figures_DG.Items.Add(new Figurez
                {
                    Figure_ID = "Fig " + i.ToString(),
                    Figure_Name = Figures_Name[i]

                });
            }

            Figures_DG.Columns.Add(new DataGridTextColumn { Header = "ID", Binding = new Binding("Figure_ID"), Width = 40, MinWidth = 40 });
            Figures_DG.Columns.Add(new DataGridTextColumn { Header = "Lable", Binding = new Binding("Figure_Name"), Width = new DataGridLength(100, DataGridLengthUnitType.Star), MinWidth = 130 });

            number_of_drawn_figures++;

            Add_this_Figure_L.Content = "Add this Figure";

            Process_and_Details_Tab.SelectedIndex = 0;
        }
        #endregion



        #region -_-             Transformation Illustration            -_-

        // Start Animation button
        private void Start_Illustration_Show_MouseEnter(object sender, MouseEventArgs e)
        {
            Start_Illustration_Show.Foreground = Button_Mouse_Enter_Color;
        }
        private void Start_Illustration_Show_MouseLeave(object sender, MouseEventArgs e)
        {
            Start_Illustration_Show.Foreground = Button_Mouse_Leave_Color;
        }
        private void Start_Illustration_Show_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Start_Illustration_Show.IsEnabled = false;
            Start_Illustration_Show.Foreground = new SolidColorBrush(Colors.Gray);

            Read_Transformation();

            switch (Start_Illustration_Show.Content.ToString())
            {
                case "Start Illustrate":
                    if (Animation_Type_B.IsChecked == true)
                        Illustrate_2nd_type_Animation();
                    else
                        Illustrate_1st_type_Animation();
                    break;

                case "Replay":
                    if (Animation_Type_B.IsChecked == true)
                        Move_Fig_A_2_Strat_Position();
                    else
                        Move_Fig_A_2_Center();
                    break;

                case "Continue":
                    Ill_2nd_T_P2();
                    break;
            }
        }


        // Back to Main menu button
        private void Back_2_Reasoning_in_Illustration_MouseEnter(object sender, MouseEventArgs e)
        {
            Back_2_Reasoning_in_Illustration.Foreground = Button_Mouse_Enter_Color;
        }
        private void Back_2_Reasoning_in_Illustration_MouseLeave(object sender, MouseEventArgs e)
        {
            Back_2_Reasoning_in_Illustration.Foreground = Button_Mouse_Leave_Color;
        }
        private void Back_2_Reasoning_in_Illustration_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Process_and_Details_Tab.SelectedIndex = 0;
        }

        
        // Prepare animation illustration
        private void Prepare_Illustration()
        {
            bool Go = false;
            if (Alpha_set_RB.IsChecked == true && Results_DG.SelectedIndex != -1)
            {
                Illustrating_Trans_info.Text =
                    "Rotation ( " +
                    ((Alpha_Details)Results_DG.Items.GetItemAt(Results_DG.SelectedIndex)).
                    Corresponding_Rotation_Angle.ToString() + " °" +
                    " ) , Move ( X :  0 , Y :  0" + " )";

                Match_ratio_in_Illustration.Text = "0";

                Go = true;
            }
            else
                if (Level_result.IsChecked == true && Results_DG.SelectedIndex != -1)
                {
                    Illustrating_Trans_info.Text =
                    "Rotation ( " +
                    ((Results_Details)Results_DG.Items.GetItemAt(Results_DG.SelectedIndex)).
                    Corresponding_Rotation_Angle.ToString() + " ° )";

                    Match_ratio_in_Illustration.Text =
                        ((Results_Details)Results_DG.Items.GetItemAt(Results_DG.SelectedIndex)).Match_Ratio.ToString();

                    Go = true;
                }

            if (Go)
            {
                Start_Illustration_Show.Content = "Start Illustrate";
                Start_Illustration_Show.IsEnabled = false;

                //Illustrating_Fig_A_Canvas.Children.Clear();
                //Illustrating_Fig_A_Canvas.Children.Add(Fig_A_L);

                Illustrating_Fig_A_Canvas.Height = (New_Figure_Canvas.Height * 2) / 3;
                Illustrating_Fig_A_Canvas.Width = (New_Figure_Canvas.Width * 2) / 3;

                Illustrating_Fig_B_Canvas.Height = Illustrating_Fig_A_Canvas.Height;
                Illustrating_Fig_B_Canvas.Width = Illustrating_Fig_A_Canvas.Width;

                Canvas.SetTop(Illustrating_Fig_A_Canvas, 275 - (Illustrating_Fig_A_Canvas.Height / 2));
                Canvas.SetTop(Illustrating_Fig_B_Canvas, 275 - (Illustrating_Fig_B_Canvas.Height / 2));


                if (Compared_Figs_DG.SelectedIndex != -1)
                {
                    Ill_Fig_A_index = Figure_name_index(((Compared_Figures)Compared_Figs_DG.Items.GetItemAt(Compared_Figs_DG.SelectedIndex)).Figure_1);
                    Ill_Fig_B_index = Figure_name_index(((Compared_Figures)Compared_Figs_DG.Items.GetItemAt(Compared_Figs_DG.SelectedIndex)).Figure_2);
                    Draw_Figure_A();
                    Draw_Figure_B();
                }

                Process_and_Details_Tab.SelectedIndex = 3;

                if (Ill_shown_once_before == false)
                {
                    Ill_shown_once_before = true;

                    Canvas.SetLeft(Illustrating_Fig_A_Canvas, 0.0);
                    Canvas.SetLeft(Illustrating_Fig_B_Canvas, Process_and_Details_Tab.ActualWidth - Illustrating_Fig_B_Canvas.Width - 12);
                }
                else
                    Prepare_4_new_Ill();

                Start_Illustration_Show.IsEnabled = true;
            }
        }


        // Draw Figures for animation 
        private void Draw_Figure_A()
        {
            double
                review_H = Convert.ToDouble(Illustrating_Fig_A_Canvas.Height) / max_y,
                review_W = Convert.ToDouble(Illustrating_Fig_A_Canvas.Width) / max_x;

            Fig_A_Animation_X_Step_Size = review_W;
            Fig_A_Animation_Y_Step_Size = review_H;

            List<int[]> T_Fig_A_Meets = new List<int[]>();
            int Min_X = max_x, Min_Y = max_y, Max_X = -max_x, Max_Y = -max_y;

            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                    if (Figures[Ill_Fig_A_index][x][y] == true)
                    {
                        T_Fig_A_Meets.Add(new int[] { x, y });

                        if (x < Min_X)
                            Min_X = x;

                        if (x > Max_X)
                            Max_X = x;

                        if (y < Min_Y)
                            Min_Y = y;

                        if (y > Max_Y)
                            Max_Y = y;
                    }

            if (Min_X < 0)
            {
                Min_X = Math.Abs(Min_X);
                Max_X = Max_X + Min_X;

                for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                {
                    T_Fig_A_Meets[i][0] += Min_X;
                }

                Min_X = 0;
            }
            else
                if (Max_X > max_x)
                {
                    for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                    {
                        T_Fig_A_Meets[i][0] += max_x - Max_X;
                    }

                    Min_X = Min_X + (max_x - Max_X);
                    Max_X = max_x;
                }

            if (Min_Y < 0)
            {
                Min_Y = Math.Abs(Min_Y);
                Max_Y = Max_Y + Min_Y;

                for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                {
                    T_Fig_A_Meets[i][1] += Min_Y;
                }

                Min_Y = 0;
            }
            else
                if (Max_Y > max_y)
                {
                    for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                    {
                        T_Fig_A_Meets[i][1] += max_y - Max_Y;
                    }

                    Min_Y = Min_Y + (max_y - Max_Y);
                    Max_Y = max_y;
                }


            int T_X = (int)Math.Round(max_x / 2.0) - (int)Math.Round((Max_X + Min_X) / 2.0);
            int T_Y = (int)Math.Round(max_y / 2.0) - (int)Math.Round((Max_Y + Min_Y) / 2.0);

            Dictionary<Point, bool> newPoints = new Dictionary<Point, bool>();
            foreach (var item in T_Fig_A_Meets)
            {
                Point newPoint = new Point(item[0] + T_X, item[1] + T_Y);
                if (!newPoints.ContainsKey(newPoint)) newPoints.Add(newPoint, true);
            }
            

            Color onColor = Colors.Red;
            Color offColor = Colors.Black;

            List<Color> colors = new List<Color>();
            colors.Add(Colors.Red);
            colors.Add(Colors.Black);
            BitmapPalette palette = new BitmapPalette(colors);
            PixelFormat pixelFormat = PixelFormats.Bgra32;

            int stride = max_x * 4;

            byte[] pixels = new byte[max_y * stride];
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                {
                    if (newPoints.ContainsKey(new Point(x, y)))
                    {
                        pixels[(x * 4) + (y * stride) + 0] = onColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = onColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = onColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = onColor.A;
                    }
                    else
                    {
                        pixels[(x * 4) + (y * stride) + 0] = offColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = offColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = offColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = offColor.A;
                    }
                }


            var bitmap = BitmapSource.Create(max_x, max_y, 96, 96, pixelFormat, palette, pixels, stride);
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = bitmap;
            Illustrating_Fig_A_Canvas.Background = ib;

            /*for (int i = 0; i < T_Fig_A_Meets.Count; i++)
            {
                Rectangle On_Pixel = new Rectangle();
                On_Pixel.Width = review_W;
                On_Pixel.Height = review_H;
                On_Pixel.Fill = Fig_A_Animation_Pixel_Brush;
                Canvas.SetLeft(On_Pixel, (T_Fig_A_Meets[i][0] + T_X) * review_W);
                Canvas.SetTop(On_Pixel, (T_Fig_A_Meets[i][1] + T_Y) * review_H);
                Illustrating_Fig_A_Canvas.Children.Add(On_Pixel);
            }*/

            Rectangle Grid_Outline = new Rectangle();
            Grid_Outline.Width = Illustrating_Fig_A_Canvas.Width;
            Grid_Outline.Height = Illustrating_Fig_A_Canvas.Height;
            Grid_Outline.Fill = new SolidColorBrush(Colors.Transparent);
            Grid_Outline.Stroke = new SolidColorBrush(Colors.Black);
            Grid_Outline.StrokeThickness = 1;
            Illustrating_Fig_A_Canvas.Children.Add(Grid_Outline);
            Canvas.SetTop(Grid_Outline, 0);
            Canvas.SetLeft(Grid_Outline, 0);

            Canvas.SetTop(Fig_A_L, 5);
            Canvas.SetLeft(Fig_A_L, Illustrating_Fig_A_Canvas.Width - 90);
        }
        private void Draw_Figure_B()
        {
            double
                   review_H = Convert.ToDouble(Illustrating_Fig_B_Canvas.Height) / max_y,
                   review_W = Convert.ToDouble(Illustrating_Fig_B_Canvas.Width) / max_x;

            List<int[]> T_Fig_B_Meets = new List<int[]>();
            int Min_X = max_x, Min_Y = max_y, Max_X = -max_x, Max_Y = -max_y;

            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                    if (Figures[Ill_Fig_B_index][x][y] == true)
                    {
                        T_Fig_B_Meets.Add(new int[] { x, y });

                        if (x < Min_X)
                            Min_X = x;

                        if (x > Max_X)
                            Max_X = x;

                        if (y < Min_Y)
                            Min_Y = y;

                        if (y > Max_Y)
                            Max_Y = y;
                    }

            if (Min_X < 0)
            {
                Min_X = Math.Abs(Min_X);
                Max_X = Max_X + Min_X;

                for (int i = 0; i < T_Fig_B_Meets.Count; i++)
                {
                    T_Fig_B_Meets[i][0] += Min_X;
                }

                Min_X = 0;
            }
            else
                if (Max_X > max_x)
                {
                    for (int i = 0; i < T_Fig_B_Meets.Count; i++)
                    {
                        T_Fig_B_Meets[i][0] += max_x - Max_X;
                    }

                    Min_X = Min_X + (max_x - Max_X);
                    Max_X = max_x;
                }

            if (Min_Y < 0)
            {
                Min_Y = Math.Abs(Min_Y);
                Max_Y = Max_Y + Min_Y;

                for (int i = 0; i < T_Fig_B_Meets.Count; i++)
                {
                    T_Fig_B_Meets[i][1] += Min_Y;
                }

                Min_Y = 0;
            }
            else
                if (Max_Y > max_y)
                {
                    for (int i = 0; i < T_Fig_B_Meets.Count; i++)
                    {
                        T_Fig_B_Meets[i][1] += max_y - Max_Y;
                    }

                    Min_Y = Min_Y + (max_y - Max_Y);
                    Max_Y = max_y;
                }


            int T_X = (int)Math.Round(max_x / 2.0) - (int)Math.Round((Max_X + Min_X) / 2.0);
            int T_Y = (int)Math.Round(max_y / 2.0) - (int)Math.Round((Max_Y + Min_Y) / 2.0);


            Dictionary<Point, bool> newPoints = new Dictionary<Point, bool>();
            foreach (var item in T_Fig_B_Meets)
            {
                Point newPoint = new Point(item[0] + T_X, item[1] + T_Y);
                if (!newPoints.ContainsKey(newPoint)) newPoints.Add(newPoint, true);
            }


            Color onColor = Colors.Red;
            Color offColor = Colors.Black;

            List<Color> colors = new List<Color>();
            colors.Add(Colors.Red);
            colors.Add(Colors.Black);
            BitmapPalette palette = new BitmapPalette(colors);
            PixelFormat pixelFormat = PixelFormats.Bgra32;

            int stride = max_x * 4;

            byte[] pixels = new byte[max_y * stride];
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                {
                    if (newPoints.ContainsKey(new Point(x, y)))
                    {
                        pixels[(x * 4) + (y * stride) + 0] = onColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = onColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = onColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = onColor.A;
                    }
                    else
                    {
                        pixels[(x * 4) + (y * stride) + 0] = offColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = offColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = offColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = offColor.A;
                    }
                }


            var bitmap = BitmapSource.Create(max_x, max_y, 96, 96, pixelFormat, palette, pixels, stride);
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = bitmap;
            Illustrating_Fig_B_Canvas.Background = ib;

            /*
            for (int i = 0; i < T_Fig_B_Meets.Count; i++)
            {
                Rectangle On_Pixel = new Rectangle();
                On_Pixel.Width = review_W;
                On_Pixel.Height = review_H;
                On_Pixel.Fill = Fig_B_Animation_Pixel_Brush;
                Canvas.SetLeft(On_Pixel, (T_Fig_B_Meets[i][0] + T_X) * review_W);
                Canvas.SetTop(On_Pixel, (T_Fig_B_Meets[i][1] + T_Y) * review_H);
                Illustrating_Fig_B_Canvas.Children.Add(On_Pixel);
            }*/

            Rectangle Grid_Outline = new Rectangle();
            Grid_Outline.Width = Illustrating_Fig_B_Canvas.Width;
            Grid_Outline.Height = Illustrating_Fig_B_Canvas.Height;
            Grid_Outline.Fill = new SolidColorBrush(Colors.Transparent);
            Grid_Outline.Stroke = new SolidColorBrush(Colors.Black);
            Grid_Outline.StrokeThickness = 1;
            Illustrating_Fig_B_Canvas.Children.Add(Grid_Outline);
            Canvas.SetTop(Grid_Outline, 0);
            Canvas.SetLeft(Grid_Outline, 0);

            Canvas.SetTop(Fig_B_L, 5);
            Canvas.SetLeft(Fig_B_L, Illustrating_Fig_B_Canvas.Width - 90);
        }

        private int Figure_name_index(string F_Name)
        {
            int v2r = -1;
            for (int i = 0; i < Figures_Name.Count; i++)
                if (Figures_Name[i] == F_Name)
                {
                    v2r = i;
                    i = Figures_Name.Count;
                }
            return v2r;
        }

        # region Transformation Illustration Region

        private void Illustrate_1st_type_Animation()
        {
            DoubleAnimation Move_Fig_B_2_Center = new DoubleAnimation();
            Move_Fig_B_2_Center.From = Canvas.GetLeft(Illustrating_Fig_B_Canvas);
            Move_Fig_B_2_Center.To =
                (Process_and_Details_Tab.ActualWidth / 2) - (Illustrating_Fig_B_Canvas.Width / 2);
            Move_Fig_B_2_Center.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text)));

            DoubleAnimation Fig_A_Opacity = new DoubleAnimation();
            Fig_A_Opacity.From = Illustrating_Fig_A_Canvas.Opacity;
            Fig_A_Opacity.To = 0.2;
            Fig_A_Opacity.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Move_Fig_B_2_Center.Completed += new EventHandler(Move_Fig_B_2_Center_Completed);

            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_B_2_Center);
            Illustrating_Fig_A_Canvas.BeginAnimation(OpacityProperty, Fig_A_Opacity);
        }
        private void Move_Fig_B_2_Center_Completed(object sender, EventArgs e)
        {
            DoubleAnimation Move_Fig_A_2_Center = new DoubleAnimation();
            Move_Fig_A_2_Center.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_Center.To = (Process_and_Details_Tab.ActualWidth / 2) - (Illustrating_Fig_A_Canvas.Width / 2);
            Move_Fig_A_2_Center.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text)));

            DoubleAnimation Fig_A_Opacity = new DoubleAnimation();
            Fig_A_Opacity.From = Illustrating_Fig_A_Canvas.Opacity;
            Fig_A_Opacity.To = 1;
            Fig_A_Opacity.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Move_Fig_A_2_Center.Completed += new EventHandler(Move_Fig_A_2_Center_Completed);

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_A_2_Center);
            Illustrating_Fig_A_Canvas.BeginAnimation(OpacityProperty, Fig_A_Opacity);
        }
        private void Move_Fig_A_2_Center_Completed(object sender, EventArgs e)
        {
            if (Trans_Rotation != 0)
            {
                DoubleAnimation Fig_A_Rotation = new DoubleAnimation();
                Fig_A_Rotation.From = 0;
                Fig_A_Rotation.To = Trans_Rotation;
                Fig_A_Rotation.Duration = new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text)));

                Fig_A_Rotation.Completed += new EventHandler(Fig_A_Rotation_Completed);

                RotateTransform Fig_A_R = new RotateTransform();

                Illustrating_Fig_A_Canvas.RenderTransform = Fig_A_R;
                //Illustrating_Fig_A_Canvas.RenderTransformOrigin = new Point(0.5, 0.5);

                Fig_A_R.BeginAnimation(RotateTransform.AngleProperty, Fig_A_Rotation);
            }
            else
            {
                DoubleAnimation Fig_A_Horizantal_Move = new DoubleAnimation();
                Fig_A_Horizantal_Move.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
                Fig_A_Horizantal_Move.To =
                    Canvas.GetLeft(Illustrating_Fig_A_Canvas) +
                    (Trans_move_X * Fig_A_Animation_X_Step_Size) +
                    (Canvas.GetLeft(Illustrating_Fig_B_Canvas) - Canvas.GetLeft(Illustrating_Fig_A_Canvas));

                Fig_A_Horizantal_Move.Duration =
                    new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) * 2));

                DoubleAnimation Fig_A_Vertical_Move = new DoubleAnimation();
                Fig_A_Vertical_Move.From = Canvas.GetTop(Illustrating_Fig_A_Canvas);
                Fig_A_Vertical_Move.To =
                    Canvas.GetTop(Illustrating_Fig_A_Canvas) +
                    (Trans_move_Y * Fig_A_Animation_Y_Step_Size) +
                    (Canvas.GetTop(Illustrating_Fig_B_Canvas) - Canvas.GetTop(Illustrating_Fig_A_Canvas));

                Fig_A_Vertical_Move.Duration =
                    new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) * 2));

                Fig_A_Horizantal_Move.Completed += new EventHandler(Fig_A_Horizantal_Move_Completed);

                Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Fig_A_Horizantal_Move);
                Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.TopProperty, Fig_A_Vertical_Move);
            }
        }
        private void Move_Fig_A_2_Center()
        {
            Illustrating_Fig_A_Canvas.Opacity = 0.2;

            DoubleAnimation Move_Fig_A_2_Center_H = new DoubleAnimation();
            Move_Fig_A_2_Center_H.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_Center_H.To = (Process_and_Details_Tab.ActualWidth / 2) - (Illustrating_Fig_A_Canvas.Width / 2);
            Move_Fig_A_2_Center_H.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 4));

            DoubleAnimation Move_Fig_A_2_Center_V = new DoubleAnimation();
            Move_Fig_A_2_Center_V.From = Canvas.GetTop(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_Center_V.To = 275 - (Illustrating_Fig_A_Canvas.Height / 2);
            Move_Fig_A_2_Center_V.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 4));

            Move_Fig_A_2_Center_H.Completed += new EventHandler(Move_Fig_A_2_Center_Completed);

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_A_2_Center_H);
            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.TopProperty, Move_Fig_A_2_Center_V);
        }
        private void Fig_A_Rotation_Completed(object sender, EventArgs e)
        {
            DoubleAnimation Fig_A_Horizantal_Move = new DoubleAnimation();

            double test = Canvas.GetLeft(Illustrating_Fig_B_Canvas) - Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            double test2 = Canvas.GetLeft(Illustrating_Fig_B_Canvas);
            double test3 = Canvas.GetLeft(Illustrating_Fig_A_Canvas);


            Fig_A_Horizantal_Move.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Fig_A_Horizantal_Move.To =
                    Canvas.GetLeft(Illustrating_Fig_A_Canvas) +
                    (Trans_move_X * Fig_A_Animation_X_Step_Size) +
                    ((Canvas.GetLeft(Illustrating_Fig_B_Canvas) - Canvas.GetLeft(Illustrating_Fig_A_Canvas)) * Fig_A_Animation_X_Step_Size);

            Fig_A_Horizantal_Move.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) * 2));

            DoubleAnimation Fig_A_Vertical_Move = new DoubleAnimation();
            Fig_A_Vertical_Move.From = Canvas.GetTop(Illustrating_Fig_A_Canvas);
            Fig_A_Vertical_Move.To =
                    Canvas.GetTop(Illustrating_Fig_A_Canvas) +
                    (Trans_move_Y * Fig_A_Animation_Y_Step_Size) +
                    ((Canvas.GetTop(Illustrating_Fig_B_Canvas) - Canvas.GetTop(Illustrating_Fig_A_Canvas)) * Fig_A_Animation_Y_Step_Size);

            Fig_A_Vertical_Move.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) * 2));

            Fig_A_Horizantal_Move.Completed += new EventHandler(Fig_A_Horizantal_Move_Completed);

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Fig_A_Horizantal_Move);
            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.TopProperty, Fig_A_Vertical_Move);
        }
        private void Fig_A_Horizantal_Move_Completed(object sender, EventArgs e)
        {
            Start_Illustration_Show.IsEnabled = true;
            Start_Illustration_Show.Foreground = new SolidColorBrush(Colors.White);
            Start_Illustration_Show.Content = "Replay";
        }
        private void Read_Transformation()
        {
            Trans_move_X = 0;
            Trans_move_Y = 0;
            Trans_Rotation = 0;

            for (int i = 0; i < Illustrating_Trans_info.Text.Length; i++)
            {
                switch (Illustrating_Trans_info.Text[i])
                {
                    case 'R':
                        Trans_Rotation = Read_Trans_illustration_info(9, Illustrating_Trans_info.Text.Length, Illustrating_Trans_info.Text);
                        i = 9 + Trans_Rotation.ToString().Length;
                        break;

                    case 'M':
                        int j = 0;
                        for (j = i + 6; j < Illustrating_Trans_info.Text.Length; j++)
                            switch (Illustrating_Trans_info.Text[j])
                            {
                                case 'X':
                                case 'x':
                                    for (int j2 = j; j2 < Illustrating_Trans_info.Text.Length; j2++)
                                        if (Illustrating_Trans_info.Text[j2] == ':')
                                        {
                                            Trans_move_X =
                                                Read_Trans_illustration_info(
                                                j2 + 1, Illustrating_Trans_info.Text.Length, Illustrating_Trans_info.Text);
                                            j = j2;
                                            j2 = Illustrating_Trans_info.Text.Length;
                                        }
                                    break;

                                case 'Y':
                                case 'y':
                                    for (int j2 = j; j2 < Illustrating_Trans_info.Text.Length; j2++)
                                        if (Illustrating_Trans_info.Text[j2] == ':')
                                        {
                                            Trans_move_Y =
                                                Read_Trans_illustration_info(
                                                j2 + 1, Illustrating_Trans_info.Text.Length, Illustrating_Trans_info.Text);
                                            j = j2;
                                            j2 = Illustrating_Trans_info.Text.Length;
                                        }
                                    break;
                            }
                        i = j;
                        break;
                }
            }
        }

        

        private Double Read_Trans_illustration_info(int Start_Read, int End_Read, string Text_to_Read)
        {
            bool SR = false; // Start Reading

            SR = false;
            string T_i_i = ""; // Transformation illustartion info

            string t = Text_to_Read[Start_Read].ToString();
            for (int j = Start_Read; j < End_Read; j++)
                switch (Text_to_Read[j])
                {
                    case '-':
                        if (SR == true)
                            if (T_i_i.Length == 0)
                                T_i_i += "-";
                        break;
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                    case '.':
                        T_i_i += Text_to_Read[j].ToString();
                        break;

                    case ' ':
                    case ':':
                        if (SR == false)
                            SR = true;
                        else
                            if (T_i_i.Length != 0)
                                j = End_Read;
                        break;
                }

            if (String.IsNullOrEmpty(T_i_i.Trim())) T_i_i = "0";

            return Convert.ToDouble(T_i_i);
        }


        private void Illustrate_2nd_type_Animation()
        {
            Illustrating_Fig_A_Canvas.Children.Clear();

            double
                review_H = Convert.ToDouble(Illustrating_Fig_A_Canvas.Height / max_y),
                review_W = Convert.ToDouble(Illustrating_Fig_A_Canvas.Width / max_x);

            double Angle = (Math.PI * (360 - Trans_Rotation)) / (double)180;

            List<int[]> T_Fig_A_Meets = new List<int[]>();
            int Min_X = max_x, Min_Y = max_y, Max_X = -max_x, Max_Y = -max_y;

            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                    if (Figures[Ill_Fig_A_index][x][y] == true)
                    {
                        int[] T = new int[] { 0, 0 };

                        T[0] = Convert.ToInt32(Math.Round(
                            x * Math.Cos(Angle) -
                            y * Math.Sin(Angle)));

                        T[1] = Convert.ToInt32(Math.Round(
                            x * Math.Sin(Angle) +
                            y * Math.Cos(Angle)));

                        if (T[0] < Min_X)
                            Min_X = T[0];

                        if (T[0] > Max_X)
                            Max_X = T[0];

                        if (T[1] < Min_Y)
                            Min_Y = T[1];

                        if (T[1] > Max_Y)
                            Max_Y = T[1];

                        T_Fig_A_Meets.Add(T);
                    }

            int T_X = 0, T_Y = 0;

            if (Min_X < 0)
            {
                Min_X = Math.Abs(Min_X);
                Max_X = Max_X + Min_X;

                for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                {
                    T_Fig_A_Meets[i][0] += Min_X;
                }

                Min_X = 0;
            }
            else
                if (Max_X > max_x)
                {
                    for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                    {
                        T_Fig_A_Meets[i][0] += max_x - Max_X;
                    }

                    Min_X = Min_X + (max_x - Max_X);
                    Max_X = max_x;
                }

            if (Min_Y < 0)
            {
                Min_Y = Math.Abs(Min_Y);
                Max_Y = Max_Y + Min_Y;

                for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                {
                    T_Fig_A_Meets[i][1] += Min_Y;
                }

                Min_Y = 0;
            }
            else
                if (Max_Y > max_y)
                {
                    for (int i = 0; i < T_Fig_A_Meets.Count; i++)
                    {
                        T_Fig_A_Meets[i][1] += max_y - Max_Y;
                    }

                    Min_Y = Min_Y + (max_y - Max_Y);
                    Max_Y = max_y;
                }


            T_X = (int)Math.Round(max_x / 2.0) - (int)Math.Round((Max_X + Min_X) / 2.0);
            T_Y = (int)Math.Round(max_y / 2.0) - (int)Math.Round((Max_Y + Min_Y) / 2.0);

            Dictionary<Point, bool> newPoints = new Dictionary<Point, bool>();
            foreach (var item in T_Fig_A_Meets)
            {
                Point newPoint = new Point(item[0] + T_X, item[1] + T_Y);
                if(!newPoints.ContainsKey(newPoint)) newPoints.Add(newPoint, true);
            }


            Color onColor = Colors.Red;
            Color offColor = Colors.Black;

            List<Color> colors = new List<Color>();
            colors.Add(Colors.Red);
            colors.Add(Colors.Black);
            BitmapPalette palette = new BitmapPalette(colors);
            PixelFormat pixelFormat = PixelFormats.Bgra32;

            int stride = max_x * 4;

            byte[] pixels = new byte[max_y * stride];
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                {
                    if (newPoints.ContainsKey(new Point(x, y)))
                    {
                        pixels[(x * 4) + (y * stride) + 0] = onColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = onColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = onColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = onColor.A;
                    }
                    else
                    {
                        pixels[(x * 4) + (y * stride) + 0] = offColor.B;
                        pixels[(x * 4) + (y * stride) + 1] = offColor.G;
                        pixels[(x * 4) + (y * stride) + 2] = offColor.R;
                        pixels[(x * 4) + (y * stride) + 3] = offColor.A;
                    }
                }


            var bitmap = BitmapSource.Create(max_x, max_y, 96, 96, pixelFormat, palette, pixels, stride);
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = bitmap;
            Illustrating_Fig_A_Canvas.Background = ib;
            /*
            SolidColorBrush RPB = new SolidColorBrush(Color.FromArgb(255, 90, 148, 255)); // Rotation Pixel Brush
            for (int i = 0; i < T_Fig_A_Meets.Count; i++)
            {
                Rectangle On_Pixel = new Rectangle();
                On_Pixel.Width = review_W;
                On_Pixel.Height = review_H;
                On_Pixel.Fill = RPB;
                Canvas.SetLeft(On_Pixel, (T_Fig_A_Meets[i][0] + T_X) * review_W);
                Canvas.SetTop(On_Pixel, (T_Fig_A_Meets[i][1] + T_Y) * review_H);
                Illustrating_Fig_A_Canvas.Children.Add(On_Pixel);
            }*/

            Rectangle Grid_Outline = new Rectangle();
            Grid_Outline.Width = Illustrating_Fig_A_Canvas.Width;
            Grid_Outline.Height = Illustrating_Fig_A_Canvas.Height;
            Grid_Outline.Fill = new SolidColorBrush(Colors.Transparent);
            Grid_Outline.Stroke = new SolidColorBrush(Colors.Black);
            Grid_Outline.StrokeThickness = 1;
            Illustrating_Fig_A_Canvas.Children.Add(Grid_Outline);
            Canvas.SetTop(Grid_Outline, 0);
            Canvas.SetLeft(Grid_Outline, 0);

            //Illustrating_Fig_A_Canvas.Children.Add(Fig_A_L);
            Canvas.SetTop(Fig_A_L, 5);
            Canvas.SetLeft(Fig_A_L, Illustrating_Fig_A_Canvas.Width - 90);

            //Start_Illustration_Show.Content = "Continue";
            //Start_Illustration_Show.IsEnabled = true;
        }
        private void Move_Fig_A_2_Strat_Position()
        {
            DoubleAnimation Move_Fig_A_2_SP_L = new DoubleAnimation();
            Move_Fig_A_2_SP_L.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_SP_L.To = 0;
            Move_Fig_A_2_SP_L.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            DoubleAnimation Move_Fig_B_2_SP_L = new DoubleAnimation();
            Move_Fig_B_2_SP_L.From = Canvas.GetLeft(Illustrating_Fig_B_Canvas);
            Move_Fig_B_2_SP_L.To = Process_and_Details_Tab.ActualWidth - Illustrating_Fig_B_Canvas.Width - 12;
            Move_Fig_B_2_SP_L.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            DoubleAnimation Move_Fig_B_2_SP_T = new DoubleAnimation();
            Move_Fig_B_2_SP_T.From = Canvas.GetTop(Illustrating_Fig_A_Canvas);
            Move_Fig_B_2_SP_T.To = 275 - (Illustrating_Fig_B_Canvas.Height / 2);
            Move_Fig_B_2_SP_T.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Move_Fig_A_2_SP_L.Completed += new EventHandler(Move_Fig_A_2_SP_L_Completed);

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_A_2_SP_L);
            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_B_2_SP_L);
            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.TopProperty, Move_Fig_B_2_SP_T);
        }
        private void Move_Fig_A_2_SP_L_Completed(object sender, EventArgs e)
        {
            Illustrate_2nd_type_Animation();
        }
        private void Ill_2nd_T_ini_L_Completed(object sender, EventArgs e)
        {
            Illustrating_Fig_A_Canvas.Width = Illustrating_Fig_A_Canvas.Width * 2;
            Illustrating_Fig_A_Canvas.Height = Illustrating_Fig_A_Canvas.Height * 2;

        }
        private void Ill_2nd_T_P2()
        {
            DoubleAnimation Move_Fig_B_2_Center_B = new DoubleAnimation();
            Move_Fig_B_2_Center_B.From = Canvas.GetLeft(Illustrating_Fig_B_Canvas);
            Move_Fig_B_2_Center_B.To =
                (Process_and_Details_Tab.ActualWidth / 2) - (Illustrating_Fig_B_Canvas.Width / 2);
            Move_Fig_B_2_Center_B.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text)));

            DoubleAnimation Fig_A_Opacity = new DoubleAnimation();
            Fig_A_Opacity.From = Illustrating_Fig_A_Canvas.Opacity;
            Fig_A_Opacity.To = 0.2;
            Fig_A_Opacity.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Move_Fig_B_2_Center_B.Completed += new EventHandler(Move_Fig_B_2_Center_B_Completed);

            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_B_2_Center_B);
            Illustrating_Fig_A_Canvas.BeginAnimation(OpacityProperty, Fig_A_Opacity);
        }
        private void Move_Fig_B_2_Center_B_Completed(object sender, EventArgs e)
        {
            DoubleAnimation Move_Fig_A_2_Center = new DoubleAnimation();
            Move_Fig_A_2_Center.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_Center.To = (Process_and_Details_Tab.ActualWidth / 2) - (Illustrating_Fig_A_Canvas.Width / 2);
            Move_Fig_A_2_Center.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text)));

            DoubleAnimation Fig_A_Opacity = new DoubleAnimation();
            Fig_A_Opacity.From = Illustrating_Fig_A_Canvas.Opacity;
            Fig_A_Opacity.To = 1;
            Fig_A_Opacity.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_A_2_Center);
            Illustrating_Fig_A_Canvas.BeginAnimation(OpacityProperty, Fig_A_Opacity);

            Start_Illustration_Show.Content = "Replay";
            Start_Illustration_Show.IsEnabled = true;
        }

        private void Prepare_4_new_Ill()
        {
            DoubleAnimation Move_Fig_A_2_SP_L = new DoubleAnimation();
            Move_Fig_A_2_SP_L.From = Canvas.GetLeft(Illustrating_Fig_A_Canvas);
            Move_Fig_A_2_SP_L.To = 0;
            Move_Fig_A_2_SP_L.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            DoubleAnimation Move_Fig_B_2_SP_L = new DoubleAnimation();
            Move_Fig_B_2_SP_L.From = Canvas.GetLeft(Illustrating_Fig_B_Canvas);
            Move_Fig_B_2_SP_L.To = Process_and_Details_Tab.ActualWidth - Illustrating_Fig_B_Canvas.Width - 12;
            Move_Fig_B_2_SP_L.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            DoubleAnimation Move_Fig_B_2_SP_T = new DoubleAnimation();
            Move_Fig_B_2_SP_T.From = Canvas.GetTop(Illustrating_Fig_A_Canvas);
            Move_Fig_B_2_SP_T.To = 275 - (Illustrating_Fig_B_Canvas.Height / 2);
            Move_Fig_B_2_SP_T.Duration =
                new Duration(TimeSpan.FromMilliseconds(Convert.ToDouble(Illustration_Speed.Text) / 2));

            Illustrating_Fig_A_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_A_2_SP_L);
            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.LeftProperty, Move_Fig_B_2_SP_L);
            Illustrating_Fig_B_Canvas.BeginAnimation(Canvas.TopProperty, Move_Fig_B_2_SP_T);
        }

        # endregion

        #endregion



        #region -_-                Common Functions                    -_-

        private void Initialize_temp_Matrix()
        {
            temp_Matrix.Clear();
            for (int x = 0; x < max_x; x++)
            {
                List<bool> t = new List<bool>();

                for (int y = 0; y < max_y; y++)
                    t.Add(false);

                temp_Matrix.Add(t);
            }
        }

        private void Reset_temp_Matrix()
        {
            for (int x = 0; x < max_x; x++)
                for (int y = 0; y < max_y; y++)
                    temp_Matrix[x][y] = false;
        }

        private void Copy_Temp_Matrix_2_Figures()
        {
            List<List<bool>> t2 = new List<List<bool>>();

            for (int x = 0; x < max_x; x++)
            {
                List<bool> t = new List<bool>();

                for (int y = 0; y < max_y; y++)
                    if (temp_Matrix[x][y] == false)
                        t.Add(false);
                    else
                        t.Add(true);

                t2.Add(t);
            }

            Figures.Add(t2);
        }

        private void DT_Reasoning_Run_Time_Tick(object sender, EventArgs e)
        {
            Reasoning_Time_MS++;
            if (Reasoning_Time_MS > 59)
            {
                Reasoning_Time_S++;
                Reasoning_Time_MS = 0;
            }
            if (Reasoning_Time_S > 59)
            {
                Reasoning_Time_M++;
                Reasoning_Time_S = 0;
            }
            if (Reasoning_Time_M > 59)
            {
                Reasoning_Time_H++;
                Reasoning_Time_M = 0;
            }
        }
        private void Reset_Timers()
        {
            Reasoning_Time_MS = 0;
            Reasoning_Time_S = 0;
            Reasoning_Time_M = 0;
            Reasoning_Time_H = 0;
        }

        #endregion



        #region -_-              Reasoning Engine Control              -_-
        
        private void Run_Next_Pair_Reasoning()
        {
            int
                R_A_i = -1,
                R_B_i = 0;

            Figure_A_index++;
            Figure_B_index++;

            if (Figure_A_index < Figures.Count && Figure_B_index < Figures.Count)
            {
                SCV = true;

                Compared_Figs_DG.Items.Clear();
                Compared_Figs_DG.Columns.Clear();

                #region Iterations DataGrid setter

                Iterations_DG.Columns.Clear();



                Style Cell_Style = new System.Windows.Style(typeof(DataGridCell));
                Cell_Style.Setters.Add(
                    new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center));
                Cell_Style.Setters.Add(
                    new Setter(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center));

                DataGridTextColumn I_Title = new DataGridTextColumn();
                I_Title.Header = "Iteration Title";
                I_Title.Binding = new Binding("Title");
                I_Title.Width = 108;
                I_Title.CellStyle = Cell_Style;

                DataGridTextColumn I_Timer = new DataGridTextColumn();
                I_Timer.Header = "Elapsed Time (msec)";
                I_Timer.Binding = new Binding("Time");
                I_Timer.Width = 120;
                I_Timer.CellStyle = Cell_Style;

                Iterations_DG.Columns.Add(I_Title);
                Iterations_DG.Columns.Add(I_Timer);

                #endregion

                Engine_index++;

                for (int i = 0; i <= Engine_index; i++)
                {
                    R_A_i++;
                    R_B_i++;

                    DataContext = new List<Compared_Figures>
            {
                new Compared_Figures
                {
                    Figure_1 = Figures_Name[R_A_i],
                    Figure_2 = Figures_Name[R_B_i]
                }
            };

                    Compared_Figs_DG.Items.Add(new Compared_Figures
                    {
                        Figure_1 = Figures_Name[R_A_i],
                        Figure_2 = Figures_Name[R_B_i]
                    });
                }

                Compared_Figs_DG.Columns.Add(new DataGridTextColumn { Header = "Figure A", Binding = new Binding("Figure_1"), Width = 114, MinWidth = 114 });
                Compared_Figs_DG.Columns.Add(new DataGridTextColumn { Header = "Figure B", Binding = new Binding("Figure_2"), Width = 114, MinWidth = 114 });
                Compared_Figs_DG.SelectedIndex = Engine_index;

                SCV = false;

                #region Check Parameters

                if (Upsilon == -1)
                {
                    Upsilon = Default_Upsilon;
                    Upsilon_TB.Text = Upsilon.ToString();
                }

                if (Epsilon == -1)
                {
                    Epsilon = Default_Epsilon;
                    Epsilon_TB.Text = Epsilon.ToString();
                }

                if (Lambda == -1)
                {
                    Lambda = Default_Lambda;
                    Lambda_TB.Text = Lambda.ToString();
                }

                if (Omega == -1)
                {
                    Omega = Default_Omega;
                    Omega_TB.Text = Omega.ToString();
                }
                #endregion

                GammaContents_RB.IsEnabled = true;
                GammaDistribution_RB.IsEnabled = true;
                Level_result.IsEnabled = true;
                Alpha_set_RB.IsEnabled = true;
                Level_result_graph.IsEnabled = true;
                All_result_graph.IsEnabled = true;

                Illustrate_Transformation_L.IsEnabled = true;
                Segmentation_Chart_L.IsEnabled = true;

                if (Process_Neighbors.IsChecked == false)
                {
                    Run_Reasoning_Background_Worker.RunWorkerAsync(0);
                }
                else if (Akin_2_Iteration.IsChecked == true)
                {
                    Run_Reasoning_Background_Worker.RunWorkerAsync(-1);
                }
                else
                    Run_Reasoning_Background_Worker.RunWorkerAsync(Convert.ToInt32(Constant_Neighbor_C_TB.Text));
                
            }
            else
            {
                DT_Reasoning_Run_Time.Stop();
            }
        }

        private void Run_Reasoning_Background_Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Engine.Add(new Reasoning_Engine());

            Engine[Engine.Count - 1].Figure_A = Figures[Figure_A_index];


            Engine[Engine.Count - 1].Figure_B = Figures[Figure_B_index];

            Run_Reasoning_Background_Worker.ReportProgress(Engine[Engine.Count - 1].Rotation_Angle);
            Run_Reasoning_Background_Worker.ReportProgress(Engine[Engine.Count - 1].Reasoning_Level);

            Engine[Engine_index].Rotation_AngleValueChanged += new EventHandler<ValueEventArgs>(RE_Rotation_AngleValueChanged);
            Engine[Engine_index].Reasoning_Level_in_Process += new EventHandler<ValueEventArgs>(RE_Reasoning_Level_in_Process);

            Engine[Engine_index].Desired_Percesion = Epsilon;
            Engine[Engine_index].Omega = Omega;
            Engine[Engine_index].d = d;
            Engine[Engine_index].Lambda = Lambda;
            Engine[Engine_index].Upsilon = Upsilon;
            Engine[Engine_index].Neighbors = (int)e.Argument;

            Engine[Engine.Count - 1].Run_Reasoning();
        }
        private void Run_Reasoning_Background_Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Match_Description.Visibility = Visibility.Visible;

            Run_Next_Pair_Reasoning();
        }
        private void Run_Reasoning_Background_Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.UserState != null)
                switch (e.UserState.ToString())
                {
                    case "Reasoning Level":
                        if (e.ProgressPercentage == Omega)
                        {
                            Start = DateTime.Now;
                            Iteration_Results.Add(new Iteration_Results_Class());
                            Iteration_Results[e.ProgressPercentage - Omega].Title =
                                "L = " + e.ProgressPercentage.ToString();
                            Iteration_Results[e.ProgressPercentage - Omega].Time = "Running";
                        }
                        else
                            if (e.ProgressPercentage == 1000000)
                            {
                                Iteration_Results[Iteration_Results.Count - 1].Time =
                                    (DateTime.Now.Subtract(Start).TotalMilliseconds).ToString();

                                Iterations_DG.Items.Refresh();
                            }
                            else
                            {
                                Iteration_Results[e.ProgressPercentage - Omega - 1].Time =
                                       (DateTime.Now.Subtract(Start).TotalMilliseconds).ToString();

                                Iterations_DG.Items.Refresh();

                                Start = DateTime.Now;
                                Iteration_Results.Add(new Iteration_Results_Class());
                                Iteration_Results[e.ProgressPercentage - Omega].Title =
                                    "L = " + e.ProgressPercentage.ToString();
                                Iteration_Results[e.ProgressPercentage - Omega].Time = "Running";
                            }
                        break;
                }
        }
        private void RE_Rotation_AngleValueChanged(object sender, ValueEventArgs e)
        {
            Run_Reasoning_Background_Worker.ReportProgress(e.Value, "Rotation_Angle");
        }
        private void RE_Reasoning_Level_in_Process(object sender, ValueEventArgs e)
        {
            Run_Reasoning_Background_Worker.ReportProgress(e.Value, "Reasoning Level");
        }
        private void RE_Scale_X_Factor_in_Process(object sender, ValueEventArgs e)
        {
            Run_Reasoning_Background_Worker.ReportProgress(e.Value, "Scale X");
        }
        private void RE_Scale_Y_Factor_in_Process(object sender, ValueEventArgs e)
        {
            Run_Reasoning_Background_Worker.ReportProgress(e.Value, "Scale Y");
        }

        #endregion



        #region -_-                       Chart                        -_-
        
        // Back to Main menu
        private void Back_to_reasoning_Charts_Tab_MouseEnter(object sender, MouseEventArgs e)
        {
            Back_to_reasoning_Charts_Tab.Foreground = Button_Mouse_Enter_Color;
        }
        private void Back_to_reasoning_Charts_Tab_MouseLeave(object sender, MouseEventArgs e)
        {
            Back_to_reasoning_Charts_Tab.Foreground = Button_Mouse_Leave_Color;
        }
        private void Back_to_reasoning_Charts_Tab_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Process_and_Details_Tab.SelectedIndex = 0;
        }


        private void My_Chart_Fig_A(List<List<int>> Source_Data)
        {
            Loading_Chart_A.Visibility = Visibility.Visible;

            if (Draw_Chart_A_Background_Worder.IsBusy == false)
                Draw_Chart_A_Background_Worder.RunWorkerAsync(Source_Data);
        }
        private void My_Chart_Fig_B(List<List<int>> Source_Data)
        {
            Loading_Chart_B.Visibility = Visibility.Visible;

            if (Draw_Chart_B_Background_Worder.IsBusy == false)
                Draw_Chart_B_Background_Worder.RunWorkerAsync(Source_Data);


            /*
            int
                N = 0,
                M = 0,
                Max_score = 0,
                Min_score = 0;

            Fig_B_Chart_Canvas.Children.Clear();

            double Canvas_Height = Fig_B_Scale_Canvas.Height;

            N = Source_Data.Count;
            M = Source_Data[0].Count;

            Min_score = 999999999;

            for (int i = 0; i < N; i++)
                for (int j = 0; j < M; j++)
                {
                    if (Source_Data[i][j] > Max_score)
                        Max_score = Source_Data[i][j];

                    if (Source_Data[i][j] < Min_score)
                        Min_score = Source_Data[i][j];
                }

            Fig_B_S_V3.Content = Max_score.ToString();
            Fig_B_S_V2.Content = ((Max_score - Min_score) / 2).ToString();
            Fig_B_S_V1.Content = Min_score.ToString();

            double Scale_Lines_Width = 0;
            Scale_Lines_Width = Math.Round(Fig_B_Scale_Canvas.Width / ((Max_score - Min_score) + 1), 1);

            Hashtable Color_Codes = new Hashtable();

            byte[] RGB;

            Fig_B_Scale_Canvas.Children.Clear();

            for (int i = 0; i <= Max_score - Min_score; i++)
            {
                if (!Color_Codes.Contains(i))
                    Color_Codes.Add(i, Convert_score_to_Color(Max_score, i));

                RGB = (byte[])Color_Codes[i];

                Rectangle Rectangle_ = new Rectangle();
                Rectangle_.Width = Math.Round(Scale_Lines_Width + 0.3, 1);
                Rectangle_.Height = Canvas_Height;
                Rectangle_.Fill = new SolidColorBrush(Color.FromArgb(255, RGB[0], RGB[1], RGB[2]));
                Canvas.SetLeft(Rectangle_, Math.Round(i * Scale_Lines_Width, 1));
                Canvas.SetTop(Rectangle_, 0);
                Fig_B_Scale_Canvas.Children.Add(Rectangle_);
            }


            double Height = Fig_B_Chart_Canvas.Height;
            double Width = Fig_B_Chart_Canvas.Width;

            const double pi = Math.PI;

            double
                a = 0.0,
                b = 0.0,
                c = 0.0,
                d = 0.0,
                x1 = 0.0,
                x2 = 0.0,
                x3 = 0.0,
                x4 = 0.0,
                uV = ((Math.Min(Height, Width)) / 2) - 10,//Math.Sqrt(Math.Pow(Height, 2) + Math.Pow(Width, 2)) / 2.0, // Unit Vector
                sX = Width / 2.0,
                sY = Height / 2.0,
                n_prime_Low = 0.0,
                n_prime_Heigh = 0.0;

            int
                x_sign = 0,
                y_sign = 0;


            for (int n = 1; n <= N; n++)
            {
                for (int m = 1; m <= M; m++)
                {
                    n_prime_Heigh = 360 - ((360.0 / N) * (n - 1.0));
                    n_prime_Low = 360 - ((360.0 / N) * n);

                    if (n_prime_Heigh >= 0 && n_prime_Heigh < 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh == 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 90 && n_prime_Heigh <= 180)
                    {
                        x_sign = -1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 180 && n_prime_Heigh < 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh == 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh > 270 && n_prime_Heigh <= 360)
                    {
                        x_sign = 1;
                        y_sign = -1;
                    }



                    if (n_prime_Heigh == 90 || n_prime_Heigh == 270)
                    {
                        a = Math.Abs(Math.Tan((n_prime_Heigh + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        a = Math.Abs(Math.Tan(n_prime_Heigh * (pi / 180.0)));
                    }

                    if (n_prime_Low == 90 || n_prime_Low == 270)
                    {
                        b = Math.Abs(Math.Tan((n_prime_Low + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        b = Math.Abs(Math.Tan(n_prime_Low * (pi / 180.0)));
                    }

                    c = (uV / M) * (m - 1.0);
                    d = (uV / M) * m;

                    x1 = c / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x2 = d / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x3 = d / Math.Sqrt(Math.Pow(b, 2) + 1.0);
                    x4 = c / Math.Sqrt(Math.Pow(b, 2) + 1.0);

                    Fig_B_Chart_Canvas.Children.Add(
                        Draw_Segment(
                        sX + (x_sign * x1),       // x1
                        sY + (y_sign * (a * x1)), // y1
                        sX + (x_sign * x2),       // x2
                        sY + (y_sign * (a * x2)), // y2
                        sX + (x_sign * x3),       // x3
                        sY + (y_sign * (b * x3)), // y3
                        sX + (x_sign * x4),       // x4
                        sY + (y_sign * (b * x4)), // y4
                        (byte[])Color_Codes[Source_Data[n - 1][m - 1]]));
                }
            }*/
        }
        private byte[] Convert_score_to_Color(int Max_score, int Score)
        {
            byte R = 0, G = 0, B = 0;

            double Score_in_new_Scale = (Score * 1275) / Max_score;

            if (Score_in_new_Scale >= 0 && Score_in_new_Scale < 255)
            {
                R = (byte)(255 - Score_in_new_Scale);
                G = (byte)(255 - Score_in_new_Scale);
                B = 255;
            }
            else
                if (Score_in_new_Scale >= 255 && Score_in_new_Scale < 510)
                {
                    R = 0;
                    G = (byte)(Score_in_new_Scale - 255 + 1);
                    B = 255;
                }
                else
                    if (Score_in_new_Scale >= 510 && Score_in_new_Scale < 765)
                    {
                        R = 0;
                        G = 255;
                        B = (byte)((255 - (Score_in_new_Scale - 765)) + 1);
                    }
                    else
                        if (Score_in_new_Scale >= 765 && Score_in_new_Scale < 1020)
                        {
                            R = (byte)((Score_in_new_Scale - 765) + 1);
                            G = 255;
                            B = 0;
                        }
                        else
                            if (Score_in_new_Scale >= 1020 && Score_in_new_Scale <= 1275)
                            {
                                R = 255;
                                G = (byte)((255 - (Score_in_new_Scale - 1275)) + 1);
                                B = 0;
                            }

            return new byte[] { R, G, B };
        }
        private System.Windows.Shapes.Path Draw_Segment(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, byte[] Fill_Color)
        {
            System.Windows.Shapes.Path Path_ = new System.Windows.Shapes.Path();
            Path_.StrokeThickness = 1;
            Path_.Stroke = new SolidColorBrush(Color.FromArgb(255, Fill_Color[0], Fill_Color[1], Fill_Color[2]));
            Path_.Fill = new SolidColorBrush(Color.FromArgb(255, Fill_Color[0], Fill_Color[1], Fill_Color[2]));

            PathGeometry Path_Geometry = new PathGeometry();
            PathFigure Path_Figure = new PathFigure();

            Path_Figure.StartPoint = new Point(x1, y1);
            Path_Figure.Segments.Add(new LineSegment() { Point = new Point(x2, y2) });
            Path_Figure.Segments.Add(new LineSegment() { Point = new Point(x3, y3) });
            Path_Figure.Segments.Add(new LineSegment() { Point = new Point(x4, y4) });

            Path_Geometry.Figures.Add(Path_Figure);
            Path_.Data = Path_Geometry;

            return Path_;
        }
        

        // Chart Drawing Background Worker
        void Draw_Chart_A_Background_Worder_DoWork(object sender, DoWorkEventArgs e)
        {
            List<List<int>> Source_Data = (List<List<int>>)e.Argument;

            while (Clear_Drawn_Charts.IsBusy) { }

            int
                N = 0,
                M = 0,
                Max_score = 0,
                Min_score = 0,
                x_sign = 0,
                y_sign = 0;

            double
                Canvas_Height = 0.0,
                Scale_Lines_Width = 0,
                Height = 0.0,
                Width = 0.0,
                a = 0.0,
                b = 0.0,
                c = 0.0,
                d = 0.0,
                x1 = 0.0,
                x2 = 0.0,
                x3 = 0.0,
                x4 = 0.0,
                n_prime_Low = 0.0,
                n_prime_Heigh = 0.0;


            Hashtable Color_Codes = new Hashtable();

            byte[] RGB;

            N = Source_Data.Count;
            M = Source_Data[0].Count;

            Min_score = 999999999;

            Dispatcher.Invoke((Action)(() =>
            {
                Fig_A_Chart_Canvas.Children.Clear();

                Canvas_Height = Fig_A_Scale_Canvas.Height;
            }));
            

            for (int i = 0; i < N; i++)
                for (int j = 0; j < M; j++)
                {
                    if (Source_Data[i][j] > Max_score)
                        Max_score = Source_Data[i][j];

                    if (Source_Data[i][j] < Min_score)
                        Min_score = Source_Data[i][j];
                }


            Dispatcher.Invoke((Action)(() =>
            {
                Fig_A_S_V3.Content = Max_score.ToString();
                Fig_A_S_V2.Content = ((Max_score - Min_score) / 2).ToString();
                Fig_A_S_V1.Content = Min_score.ToString();

                Scale_Lines_Width = Math.Round(Fig_A_Scale_Canvas.Width / ((Max_score - Min_score) + 1), 1);
            }));


            Dispatcher.Invoke((Action)(() =>
            {
                Fig_A_Scale_Canvas.Children.Clear();
            }));



            for (int i = 0; i <= Max_score - Min_score; i++)
            {
                if (!Color_Codes.Contains(i))
                    Color_Codes.Add(i, Convert_score_to_Color(Max_score, i));

                RGB = Convert_score_to_Color(Max_score, i);

                Dispatcher.Invoke((Action)(() =>
                {
                    Rectangle Rectangle_ = new Rectangle();
                    Rectangle_.Width = Math.Round(Scale_Lines_Width + 0.3, 1);
                    Rectangle_.Height = Canvas_Height;
                    Rectangle_.Fill = new SolidColorBrush(Color.FromArgb(255, RGB[0], RGB[1], RGB[2]));
                    Canvas.SetLeft(Rectangle_, Math.Round(i * Scale_Lines_Width, 1));
                    Canvas.SetTop(Rectangle_, 0);

                    Fig_A_Scale_Canvas.Children.Add(Rectangle_);
                }));
            }

            Dispatcher.Invoke((Action)(() =>
                {
                    Height = Fig_A_Chart_Canvas.Height;
                    Width = Fig_A_Chart_Canvas.Width;
                }));


            double

                uV = ((Math.Min(Height, Width)) / 2) - 10,
                sX = Width / 2.0,
                sY = Height / 2.0;
                                


            for (int n = 1; n <= N; n++)
            {
                for (int m = 1; m <= M; m++)
                {
                    n_prime_Heigh = 360 - ((360.0 / N) * (n - 1.0));
                    n_prime_Low = 360 - ((360.0 / N) * n);

                    if (n_prime_Heigh >= 0 && n_prime_Heigh < 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh == 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 90 && n_prime_Heigh <= 180)
                    {
                        x_sign = -1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 180 && n_prime_Heigh < 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh == 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh > 270 && n_prime_Heigh <= 360)
                    {
                        x_sign = 1;
                        y_sign = -1;
                    }



                    if (n_prime_Low == 90 || n_prime_Low == 270)
                    {
                        a = Math.Abs(Math.Tan((((360.0 / N) * (n - 1.0)) + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        a = Math.Abs(Math.Tan(((360.0 / N) * (n - 1.0)) * (pi / 180.0)));
                    }

                    if (n_prime_Heigh == 90 || n_prime_Heigh == 270)
                    {
                        b = Math.Abs(Math.Tan((((360.0 / N) * n) + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        b = Math.Abs(Math.Tan(((360.0 / N) * n) * (pi / 180.0)));
                    }

                    c = (uV / M) * (m - 1.0);
                    d = (uV / M) * m;

                    x1 = c / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x2 = d / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x3 = d / Math.Sqrt(Math.Pow(b, 2) + 1.0);
                    x4 = c / Math.Sqrt(Math.Pow(b, 2) + 1.0);

                    Dispatcher.Invoke((Action)(() =>
                    {
                        Fig_A_Chart_Canvas.Children.Add(
                        Draw_Segment(
                        sX + (x_sign * x1),       // x1
                        sY + (y_sign * (a * x1)), // y1
                        sX + (x_sign * x2),       // x2
                        sY + (y_sign * (a * x2)), // y2
                        sX + (x_sign * x3),       // x3
                        sY + (y_sign * (b * x3)), // y3
                        sX + (x_sign * x4),       // x4
                        sY + (y_sign * (b * x4)), // y4
                        (byte[])Color_Codes[Source_Data[n - 1][m - 1]]));
                    }));
                }
            }
        }
        void Draw_Chart_A_Background_Worder_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Loading_Chart_A.Visibility = Visibility.Hidden;
        }

        void Draw_Chart_B_Background_Worder_DoWork(object sender, DoWorkEventArgs e)
        {
            List<List<int>> Source_Data = (List<List<int>>)e.Argument;

            while (Clear_Drawn_Charts.IsBusy) { }

            int
                N = 0,
                M = 0,
                Max_score = 0,
                Min_score = 0,
                x_sign = 0,
                y_sign = 0;

            double
                Canvas_Height = 0.0,
                Scale_Lines_Width = 0,
                Height = 0.0,
                Width = 0.0,
                a = 0.0,
                b = 0.0,
                c = 0.0,
                d = 0.0,
                x1 = 0.0,
                x2 = 0.0,
                x3 = 0.0,
                x4 = 0.0,
                n_prime_Low = 0.0,
                n_prime_Heigh = 0.0;


            Hashtable Color_Codes = new Hashtable();

            byte[] RGB;

            N = Source_Data.Count;
            M = Source_Data[0].Count;

            Min_score = 999999999;

            Dispatcher.Invoke((Action)(() =>
            {
                Fig_B_Chart_Canvas.Children.Clear();

                Canvas_Height = Fig_B_Scale_Canvas.Height;
            }));


            for (int i = 0; i < N; i++)
                for (int j = 0; j < M; j++)
                {
                    if (Source_Data[i][j] > Max_score)
                        Max_score = Source_Data[i][j];

                    if (Source_Data[i][j] < Min_score)
                        Min_score = Source_Data[i][j];
                }


            Dispatcher.Invoke((Action)(() =>
            {
                Fig_B_S_V3.Content = Max_score.ToString();
                Fig_B_S_V2.Content = ((Max_score - Min_score) / 2).ToString();
                Fig_B_S_V1.Content = Min_score.ToString();

                Scale_Lines_Width = Math.Round(Fig_B_Scale_Canvas.Width / ((Max_score - Min_score) + 1), 1);
            }));


            Dispatcher.Invoke((Action)(() =>
            {
                Fig_B_Scale_Canvas.Children.Clear();
            }));



            for (int i = 0; i <= Max_score - Min_score; i++)
            {
                if (!Color_Codes.Contains(i))
                    Color_Codes.Add(i, Convert_score_to_Color(Max_score, i));

                RGB = Convert_score_to_Color(Max_score, i);

                Dispatcher.Invoke((Action)(() =>
                {
                    Rectangle Rectangle_ = new Rectangle();
                    Rectangle_.Width = Math.Round(Scale_Lines_Width + 0.3, 1);
                    Rectangle_.Height = Canvas_Height;
                    Rectangle_.Fill = new SolidColorBrush(Color.FromArgb(255, RGB[0], RGB[1], RGB[2]));
                    Canvas.SetLeft(Rectangle_, Math.Round(i * Scale_Lines_Width, 1));
                    Canvas.SetTop(Rectangle_, 0);

                    Fig_B_Scale_Canvas.Children.Add(Rectangle_);
                }));
            }

            Dispatcher.Invoke((Action)(() =>
            {
                Height = Fig_B_Chart_Canvas.Height;
                Width = Fig_B_Chart_Canvas.Width;
            }));


            double

                uV = ((Math.Min(Height, Width)) / 2) - 10,
                sX = Width / 2.0,
                sY = Height / 2.0;



            for (int n = 1; n <= N; n++)
            {
                for (int m = 1; m <= M; m++)
                {
                    n_prime_Heigh = 360 - ((360.0 / N) * (n - 1.0));
                    n_prime_Low = 360 - ((360.0 / N) * n);

                    if (n_prime_Heigh >= 0 && n_prime_Heigh < 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh == 90)
                    {
                        x_sign = 1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 90 && n_prime_Heigh <= 180)
                    {
                        x_sign = -1;
                        y_sign = 1;
                    }
                    else if (n_prime_Heigh > 180 && n_prime_Heigh < 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh == 270)
                    {
                        x_sign = -1;
                        y_sign = -1;
                    }
                    else if (n_prime_Heigh > 270 && n_prime_Heigh <= 360)
                    {
                        x_sign = 1;
                        y_sign = -1;
                    }



                    if (n_prime_Low == 90 || n_prime_Low == 270)
                    {
                        a = Math.Abs(Math.Tan((((360.0 / N) * (n - 1.0)) + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        a = Math.Abs(Math.Tan(((360.0 / N) * (n - 1.0)) * (pi / 180.0)));
                    }

                    if (n_prime_Heigh == 90 || n_prime_Heigh == 270)
                    {
                        b = Math.Abs(Math.Tan((((360.0 / N) * n) + 0.00001) * (pi / 180.0)));
                    }
                    else
                    {
                        b = Math.Abs(Math.Tan(((360.0 / N) * n) * (pi / 180.0)));
                    }

                    c = (uV / M) * (m - 1.0);
                    d = (uV / M) * m;

                    x1 = c / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x2 = d / Math.Sqrt(Math.Pow(a, 2) + 1.0);
                    x3 = d / Math.Sqrt(Math.Pow(b, 2) + 1.0);
                    x4 = c / Math.Sqrt(Math.Pow(b, 2) + 1.0);

                    Dispatcher.Invoke((Action)(() =>
                    {
                        Fig_B_Chart_Canvas.Children.Add(
                        Draw_Segment(
                        sX + (x_sign * x1),       // x1
                        sY + (y_sign * (a * x1)), // y1
                        sX + (x_sign * x2),       // x2
                        sY + (y_sign * (a * x2)), // y2
                        sX + (x_sign * x3),       // x3
                        sY + (y_sign * (b * x3)), // y3
                        sX + (x_sign * x4),       // x4
                        sY + (y_sign * (b * x4)), // y4
                        (byte[])Color_Codes[Source_Data[n - 1][m - 1]]));
                    }));
                }
            }
        }
        void Draw_Chart_B_Background_Worder_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Loading_Chart_B.Visibility = Visibility.Hidden;
        }

        
        // Clearing Drawn Charts
        private void Clear_Drawn_Charts_DoWork(object sender, DoWorkEventArgs e)
        {
            Dispatcher.Invoke((Action)(() =>
            {
                Fig_A_Chart_Canvas.Children.Clear();
                Fig_B_Chart_Canvas.Children.Clear();
            }));
        }
        private void Clear_Drawn_Charts_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Clearing_Drawn_Chart_L.Visibility = Visibility.Hidden;

            Clear_Drawn_Charts.CancelAsync();
            Clear_Drawn_Charts.Dispose();
        }

        #endregion
        
    }
}
